2016-07-27 41 views
1

は、Python 2.7.12ドキュメント(。3.4.12新しいスタイルのクラス¶のための特別な方法で検索)から取得したコードスニペットです:任意のインスタンスをバイパスすることに加えなぜメタクラス__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:正確には、暗黙の特別なメソッドのルックアップは、一般的にさえも、オブジェクトのメタクラスの __getattribute__()方法をバイパス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は後者がC.__dict__に見出すことができるされていても、そうMeta.__getattribute__C.__len__がアクセスされたときに呼び出され、メタクラスMetaのインスタンスです。

実際には、C.__dict__にアクセスすることも属性アクセスであり、したがってMeta.__getattribute__が依然として呼び出されます。

関連する問題