为什么在这里调用元类 __getattribute__ ?

nal*_*zok 4 python attributes class python-2.7

这是从 Python 2.7.12 文档 ( 3.4.12. Special method lookup for new-style classes¶ ) 中检索到的代码片段:

除了为了正确性而绕过任何实例属性之外,隐式特殊方法查找通常也会绕过__getattribute__()对象元类的方法:

>>> class Meta(type):
...    def __getattribute__(*args):
...       print "Metaclass getattribute invoked"
...       return type.__getattribute__(*args)
...
>>> class C(object):
...     __metaclass__ = Meta
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print "Class getattribute invoked"
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么__getattribute__在执行时调用元类type(c).__len__(c)

由于type(c)yields C,该语句可以重写为C.__len__(c). C.__len__是定义在类中的未绑定方法,在类C中可以找到C.__dict__,那么为什么会Meta涉及到查找呢?

nal*_*zok 5

引自同一文档,3.4.2.1。新式类的更多属性访问:

object.__getattribute__(self, name)

无条件调用以实现对类实例的属性访问 。...

ClassC是 metaclass 的一个实例Meta,因此Meta.__getattribute__C.__len__访问时调用,即使后者可以在C.__dict__.

实际上,访问C.__dict__也是一种属性访问,因此Meta.__getattribute__仍然会被调用。