我观察到至少有3种与Python 3中的函数相关的类型:
>>> class A():
... def f(): pass
...
>>> A.f
<function A.f at 0x7fcaef304268>
>>> A().f
<bound method A.f of <__main__.A object at 0x7fcaef2fae80
>>> set.union
<method 'union' of 'set' objects>
我想知道'function','method'和'bound method'之间有什么区别? 'method'是否等同于Python 2中的'unbound method'?
答案 0 :(得分:6)
是&#39;方法&#39;相当于&#39;未绑定方法的类型&#39;在Python 2中?
类-A-排序一个。但不是真的。它是C代码中定义的method_descriptor
对象。它是一种未绑定的方法,但不是您在Python 2中找到的那种方法。
对于编写C的Python类型,所有&#39;方法&#39;真的是C函数。您找到的<method 'name' of 'type' objects>
对象是一个特殊对象,您可以使用该对象在给定实例和其他参数的情况下调用该函数,就像function
对象对自定义Python类所做的那样。该对象在PyMethodDescr_Type
structure中的C中定义。它实现了descriptor protocol,就像函数一样。
Python定义了其他几种这样的描述符类型;如果您使用__slots__
,则每个属性都是member_descriptor
类型的dsescriptor(请参阅PyMemberDescr_Type
structure),而classmethod
,property
和staticmethod
是也许是更好的已知描述符对象。
在Python 2中,绑定和未绑定方法实际上只是一个类型,instancemethod
(由PyMethod_Type
structure定义);如果设置了__self__
(im_self
)属性,它将作为绑定报告。在Python 3中,使用函数作为描述符根本不会产生没有__self__
集的方法对象;相反,在没有实例的情况下调用function.__get__()
只会再次返回该函数。
Python 2返回未绑定方法的唯一原因是强制执行类型检查;第一个参数必须是类的实例(或其子类)。对于支持duck-typing的Python代码,这并没有多大意义,所以在Python 3中,限制被删除了。但是,使用C代码您无法使用duck-typing,您仍然必须限制类型,这就是 C-types 仍然返回method_descriptor
对象的原因这会加强这种限制。