3

在这段代码中:

def fa(a,b): 
    print a
    print b
    print " fa called"

class A:
    @classmethod
    def fa(a,b): 
        print a
        print b
        print " A.fa called"
class B:
    def __init__(s,a):
        s.a = a

obj1 = B(A.fa)
obj1.a("xxxx")

obj2 = B(fa)
obj2.a("xxxx")

输出:

__main__.A
xxxx
A.fa called
Traceback (most recent call last):
File "test.py", line 20, in <module>
   obj2.a("xxxx")
TypeError: fa() takes exactly 2 arguments (1 given) 

为什么免费方法“fa”没有接收“self”作为第一个参数?绑定方法 A.fa 的行为符合预期。

4

2 回答 2

3

绑定方法作为第一个参数A.fa接收A,因为它是 的类方法A。无论您如何调用此函数,它都将始终A作为第一个参数接收。

free 方法fa没有绑定,所以它接收的唯一参数是传入的参数。无论你如何调用这个函数,它永远不会接收除了传入的参数之外的参数。

这种行为不同于像 JavaScript 这样的语言,其中方法的调用方式决定了上下文。在 Python 中,隐式参数传递(类似于 JavaScript 上下文)是在函数定义时确定的,并且无论如何调用该函数,该绑定或缺少绑定将始终用于该函数。

如果您想动态绑定一个免费方法,您可以使用 来执行此操作types.MethodType,例如:

def fa(x):
    print x

class B: pass

>>> obj1 = B()
>>> obj1.a = MethodType(fa, obj1)
>>> obj1.a()  # obj1.a behaves like an instance method bound to obj1
<__main__.B instance at 0x7f0589baf170>
>>> obj1.a2 = MethodType(fa, B)
>>> obj1.a2() # obj1.a2 acts like a class method bound to B
__main__.B
于 2013-09-27T19:57:49.317 回答
1

因为 doobj2.a = fa不会使a( fa) 成为 的方法obj2

>>> class A(object):
...     def meth(self, x, y):
...         print x, y
... 
>>> 
>>> a = A()
>>> 
>>> a.meth
<bound method A.meth of <__main__.A object at 0x10e281950>> # Method
>>>
>>> def fn(x, y):
...     print x, y
... 
>>> 
>>> fn
<function fn at 0x10e287140>
>>> a.fn = fn
>>> 
>>> a.fn
<function fn at 0x10e287140>  # Not a method, still a function
于 2013-09-27T19:56:21.473 回答