2016-02-10 50 views
6

我注意到,如果我在创建该类的实例时定义了一个等于某个函数的类属性,则该属性将成为一个绑定方法。有人能解释我这种行为的原因吗?Python - 作为类属性的函数成为绑定方法

In [9]: def func(): 
    ...:  pass 
    ...: 

In [10]: class A(object): 
    ....:  f = func 
    ....:  

In [11]: a = A() 

In [12]: a.f 
Out[12]: <bound method A.func of <__main__.A object at 0x104add190>> 

In [13]: a.f() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-13-19134f1ad9a8> in <module>() 
----> 1 a.f() 
    global a.f = <bound method A.func of <__main__.A object at 0x104add190>> 

TypeError: func() takes no arguments (1 given) 

回答

7

您已将函数赋值给属性f。因为函数现在在一个类内成为一个方法,特别是一个绑定方法(导致它被绑定到对象further explanation here)。

方法在课堂上接受至少一个参数(self),除非它是特意叮嘱不要 - 看class methods and static methods - ,出于这个原因,错误说func不带任何参数(因为它的定义为def func():),但收到1(self

做你想做什么,你说你使用的是static method

def func(): 
    pass 

class A(object): 
    f = staticmethod(func) 
应该告诉蟒蛇
1

Python是基于消息OO系统。相反,与JavaScript类似,属性被解析为一级函数,然后被调用;正如发现的那样,这种行为的机制有点不同。

在Python的要求是,方法具有至少一个参数,通常称为self,那将是自动当被调用作为一种方法提供的关联的实例。另外(也许就问题来说),Python在建立实例成员绑定时不区分使用def f..f = some_func();可以说这与类之外的行为相匹配。

在该示例中,将该函数分配给实例'使得它期望被视为实例方法'。在两种情况下都是完全相同的 - 无参数 - 函数;只有这样的未来使用是相关的。

现在,与JavaScript不同,Python通过绑定方法的概念处理方法和对象关联 - 功能解析为方法总是“绑定”。

a.f返回绑定方法的行为 - 将自动为第一个参数提供绑定对象的函数为self - 独立于函数源完成。在这种情况下,这意味着无参数函数在“绑定”时不能使用,因为它不接受self参数。

g = a.f 
g() 

在这种情况下主叫g()是:

作为示范,下面将用同样的方式,因为源底层方法确实满足接受实例作为参数的最低要求失败相当于拨打func(a)


为了比较,Java和C#,红宝石和Smalltalk是基于消息OO系统 - 在这些对象被告知由“名称”调用方法,代替拆分的方法(或函数)作为可调用的值。