9

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

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

1 回答 1

13

魔术__methods__()被特殊对待:它们被内部分配到类型数据结构中的“槽”以加快它们的查找速度,并且只在这些槽中查找它们。如果插槽为空,您将收到错误消息。

有关详细信息,请参阅文档中的新样式类的特殊方法查找。摘抄:

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

[…]

以这种方式绕过__getattribute__()机制为解释器中的速度优化提供了很大的空间,但代价是处理特殊方法的一些灵活性(特殊方法必须在类对象本身上设置,以便解释器始终调用) .

于 2012-07-06T10:02:54.403 回答