2016-07-27 97 views
1

下面是Python的2.7.12文档(3.4.12新风格classes¶特殊方法查找。)读出的代码片段:为什么在这里调用metaclass __getattribute__?

除了绕过任何实例中的 利益属性正确性,隐特殊方法查找通常也绕过 的__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 

我的问题是,为什么metacl执行type(c).__len__(c)时调用屁股__getattribute__

由于type(c)产生C,此声明可以改写为C.__len__(c)C.__len__是在类C中定义的未绑定方法,它可以在C.__dict__中找到,那么为什么Meta涉及查找?

回答

2

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

object.__getattribute__(self, name)

无条件实现属性访问的 实例类的。 ...

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

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