2012-07-06 28 views
9

在试图包装任意对象时,我遇到了字典和列表的问题。调查中,我设法想出了一段简单的代码,其行为我简直不明白。我希望一些你能告诉我是怎么回事:为什么__getattribute__不会对隐式__getitem __-调用调用?

>>> class Cl(object): # simple class that prints (and suppresses) each attribute lookup 
... def __getattribute__(self, name): 
...  print 'Access:', name 
... 
>>> i = Cl() # instance of class 
>>> i.test # test that __getattribute__ override works 
Access: test 
>>> i.__getitem__ # test that it works for special functions, too 
Access: __getitem__ 
>>> i['foo'] # but why doesn't this work? 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'Cl' object has no attribute '__getitem__' 

回答

12

魔术__methods__()被特殊处理:它们在内部分配给“槽”中的数据类型结构,加快他们的查找,他们是只在这些插槽中查找。如果该插槽为空,则会收到您收到的错误消息。

请参阅Special method lookup for new-style classes以获取更多详细信息。摘录:

除了绕过任何情况下在正确的利益属性,隐含的特殊方法查找通常也绕过即使对象的元类的__getattribute__()方法。

[...]

绕过以这种方式__getattribute__()机械提供显著范围为解释器内的速度最佳化,以在特殊的方法处理的一些灵活性为代价的(特殊的方法必须在类被设置对象本身以便被解释器一致地调用)。

相关问题