函数被实现为描述符。引用文档:
通常,描述符是具有“绑定行为”的对象属性,其属性访问已被描述符协议中的方法覆盖。这些方法是__get__()
、__set__()
和__delete__()
。如果为对象定义了这些方法中的任何一个,则称其为描述符。
这个想法是该__get__
方法允许识别属性是如何获取的。考虑这个简单的例子:
>>> class Descriptor(object):
... def __get__(self, obj, type=None):
... print '__get__(%r, %r)' % (obj, type)
...
>>> class A(object):
... desc = Descriptor()
...
>>> A.desc
__get__(None, <class '__main__.A'>)
>>> A().desc
__get__(<__main__.A object at 0x020F5B50>, <class '__main__.A'>)
如您所见,并且如__get__
文档中所述,该obj
参数允许通过类或实例区分属性访问。Python 的内部可以使用相同的机制在访问函数属性时返回绑定或未绑定的方法。
在实践中:
>>> class A:
... def f(self):
... pass
...
>>> A.f.__get__(None, A)
<unbound method A.f>
>>> A.f.__get__(A(), A)
<bound method A.f of <__main__.A instance at 0x022082D8>>
这都是 Python 2.x 的示例,但据我所知,Python 3.x 的工作方式相同,只是未绑定的方法是常规函数。