2012-07-06 8 views
9

任意のオブジェクトをラップしようとしているうちに、辞書やリストに問題が発生しました。調べてみると、わたしは単純に理解できない振る舞いを持つ単純なコードを思いつきました。私はあなたのいくつかは、何が起こっている私に言うことを願って:暗黙の__getitem __-呼び出しで__getattribute__が呼び出されないのはなぜですか?

>>> 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__()機械をバイパス

特別なメソッドの処理にある程度の柔軟性を犠牲に(特殊なメソッドがクラスに設定する必要があり、インタプリタ内の速度の最適化のための有意な範囲を提供インタプリタによって一貫して呼び出されるためには、オブジェクトそのもの)。