为什么在这里调用metaclass __getattribute__?

时间:2016-07-27 08:53:29

标签: python python-2.7 class attributes

这是从Python 2.7.12文档中检索到的代码片段( 3.4.12。新式类的特殊方法查找):

  

除了绕过任何实例属性之外   正确性,隐式特殊方法查找一般也绕过   甚至是对象的元类的__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

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

由于type(c)产生C,因此该语句可以重写为C.__len__(c)C.__len__是在课程C中定义的未绑定方法,可以在C.__dict__中找到,所以为什么Meta参与了查找?

1 个答案:

答案 0 :(得分:4)

来自同一文件的报价,3.4.2.1。新样式类的更多属性访问:

  

object.__getattribute__(self, name)

     

名为无条件以实现属性访问   该课程的实例。 ...

C是元类Meta的一个实例,因此在访问Meta.__getattribute__时会调用C.__len__,即使后者可以在C.__dict__中找到}。

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