Python 3 中的 'function'、'method' 和 'bound method' 有什么区别?
What's the difference between a 'function', 'method' and 'bound method' in Python 3?
我在 Python 3:
中观察到至少 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' 的类型吗?
Is 'method' a type equivalent to 'unbound method' in Python 2?
请稍等一下。但不是真的。它是一个用 C 代码定义的 method_descriptor
对象。这是一个未绑定的方法,但不是您在 Python 2.
中找到的那种方法
对于 Python 写成 C 的类型,所有 'methods' 都是真正的 C 函数。您找到的 <method 'name' of 'type' objects>
对象是一个特殊对象,您可以使用它来调用给定实例和更多参数的函数,就像 function
对象对自定义 Python classes 所做的那样.该对象在 PyMethodDescr_Type
structure. It implements the descriptor protocol 中用 C 定义,就像函数一样。
Python 定义了其他几个这样的描述符类型;如果您使用 __slots__
, each attribute is a dsescriptor of type member_descriptor
(see the PyMemberDescr_Type
structure),而 classmethod
、property
和 staticmethod
可能是更广为人知的描述符对象。
在Python 2、绑定和未绑定方法实际上只是一个类型,instancemethod
(由PyMethod_Type
structure定义);如果设置了 __self__
(im_self
) 属性,它将报告为绑定。在 Python 3 中,使用函数作为描述符在没有设置 __self__
的情况下根本不会生成方法对象;而不是在没有实例的情况下调用 function.__get__()
只是再次 return 函数。
Python 2 return 未绑定方法的唯一原因是强制执行类型检查;第一个参数必须是 class 的实例(或其子 class )。这对于支持 duck-typing 的 Python 代码没有多大意义,因此在 Python 3 中删除了限制。但是,对于 C 代码,您不能使用 duck-typing,您仍然必须限制类型,这就是为什么 C-types 仍然 return a method_descriptor
强制执行此限制的对象。
我在 Python 3:
中观察到至少 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' 的类型吗?
Is 'method' a type equivalent to 'unbound method' in Python 2?
请稍等一下。但不是真的。它是一个用 C 代码定义的 method_descriptor
对象。这是一个未绑定的方法,但不是您在 Python 2.
对于 Python 写成 C 的类型,所有 'methods' 都是真正的 C 函数。您找到的 <method 'name' of 'type' objects>
对象是一个特殊对象,您可以使用它来调用给定实例和更多参数的函数,就像 function
对象对自定义 Python classes 所做的那样.该对象在 PyMethodDescr_Type
structure. It implements the descriptor protocol 中用 C 定义,就像函数一样。
Python 定义了其他几个这样的描述符类型;如果您使用 __slots__
, each attribute is a dsescriptor of type member_descriptor
(see the PyMemberDescr_Type
structure),而 classmethod
、property
和 staticmethod
可能是更广为人知的描述符对象。
在Python 2、绑定和未绑定方法实际上只是一个类型,instancemethod
(由PyMethod_Type
structure定义);如果设置了 __self__
(im_self
) 属性,它将报告为绑定。在 Python 3 中,使用函数作为描述符在没有设置 __self__
的情况下根本不会生成方法对象;而不是在没有实例的情况下调用 function.__get__()
只是再次 return 函数。
Python 2 return 未绑定方法的唯一原因是强制执行类型检查;第一个参数必须是 class 的实例(或其子 class )。这对于支持 duck-typing 的 Python 代码没有多大意义,因此在 Python 3 中删除了限制。但是,对于 C 代码,您不能使用 duck-typing,您仍然必须限制类型,这就是为什么 C-types 仍然 return a method_descriptor
强制执行此限制的对象。