为什么在隐式__getitem __-调用时没有调用__getattribute__?

时间:2012-07-06 09:59:39

标签: python magic-methods

在尝试包装任意对象时,我遇到了字典和列表的问题。调查,我设法提出了一段简单的代码,其行为我根本不理解。我希望你们中的一些人能告诉我发生了什么:

>>> 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__'

1 个答案:

答案 0 :(得分:13)

Magic __methods__()受到特殊处理:它们在内部分配到类型数据结构中的“插槽”以加速查找,并且只在这些插槽中查找它们。如果插槽为空,则会收到错误消息。

有关详细信息,请参阅文档中的Special method lookup for new-style classes。摘录:

  

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

     

[...]

     

以这种方式绕过__getattribute__()机制为解释器内的速度优化提供了很大的空间,代价是处理特殊方法的一些灵活性(必须在类对象本身上按顺序设置特殊方法由翻译一致地调用。)