2013-05-30 33 views
3

有这样的代码:从类和从该类的实例访问功能

class B: 
    def f(self): 
     pass 

print(B.f) # <function B.f at 0xb711977c> 
print(B().f) # <bound method B.f of <__main__.B object at 0xb71774cc>> 

如何翻译知道,当功能f从类对象访问,然后返回正常的功能,但是当这个功能是从访问类实例然后绑定方法返回?我读到有一个__get__函数用于将对象与函数绑定,但是这对于类和类实例在内部是如何工作的?

+3

该机制被称为“描述符”:http://docs.python.org/2/howto/descriptor.html。尽管这是一个粗糙的实现细节。 – millimoose

回答

1

功能实现为descriptors。引用文档:

一般来说,描述符是具有“绑定行为”的对象属性,其属性访问已被描述符协议中的方法覆盖。这些方法是__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__ documentation所述,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的相同,只是未绑定的方法是定期的功能。