「python 属性ルックアップ プロセス」と言うとき、つまり x.foo と書くと python は何をしますか??
Web を検索しても、これに関するドキュメントはあまり見つかりませんでした。見つかった最高の論文の 1 つは、次の手順へのプロセスを再開しました (完全な記事はこちらで参照できます) 。
- attrname が objectname の特別な (つまり、Python が提供する) 属性である場合、それを返します。
- attrname の objectname.__class__.__dict__ を確認してください。存在し、データ記述子である場合は、記述子の結果を返します。objectname.__class__ のすべてのベースで同じケースを検索します。
- objectname.__dict__ で attrname を確認し、見つかった場合は戻ります。objectname がクラスの場合、そのベースも検索します。それがクラスであり、記述子がそのクラスまたはそのベースに存在する場合、記述子の結果を返します。
- attrname の objectname.__class__.__dict__ を確認してください。存在し、非データ記述子である場合は、記述子の結果を返します。存在し、記述子ではない場合は、それを返します。それが存在し、データ記述子である場合、ポイント 2 で戻ってきたので、ここにいるべきではありません。objectname.__class__ のすべてのベースで同じケースを検索します。
- AttributeError を発生させます。
最初はこれが正しいように思えるかもしれませんが、属性のルックアップ プロセスはもう少し複雑です。たとえば、x.foo の場合、x がクラスまたはインスタンスの場合は同じように動作しません。
この方法では説明できないサンプルがいくつか見つかりました。次の Python コードを検討してください。
class Meta(type):
def __getattribute__(self, name):
print("Metaclass getattribute invoked:", self)
return type.__getattribute__(self, name)
def __getattr__(self, item):
print('Metaclass getattr invoked: ', item)
return None
class C(object, metaclass=Meta):
def __getattribute__(self, name):
print("Class getattribute invoked:", args)
return object.__getattribute__(self, name)
c=C()
次に、対応する出力で次の行を確認します。
>> C.__new__
Metaclass getattribute invoked: <class '__main__.C'>
<built-in method __new__ of type object at 0x1E1B80B0>
>> C.__getattribute__
Metaclass getattribute invoked: <class '__main__.C'>
<function __getattribute__ at 0x01457F18>
>> C.xyz
Metaclass getattribute invoked: <class '__main__.C'>
Metaclass getattr invoked: xyz
None
>> c.__new__
Class getattribute invoked: (<__main__.C object at 0x013E7550>, '__new__')
<built-in method __new__ of type object at 0x1E1B80B0>
>> c.__getattribute__
Class getattribute invoked: (<__main__.C object at 0x01438DB0>, '__getattribute__')
Metaclass getattribute invoked: <class '__main__.C'>
<bound method C.__getattribute__ of <__main__.C object at 0x01438DB0>>
>>
私が行った結論は次のとおりです(x.fooを検索していることを考慮して):
- __getattribute__ は、< type 'type' > と < type 'object' > のインスタンスでは異なります。C.foo() の場合、C.__dict__ で最初に 'foo' が検索され、(type(C) を検索する代わりに) 見つかった場合に返され、x.foo() の場合、type(x).__dict__ で 'foo' が検索され、 x.__dict__ で。
- __getattribute__ メソッドは常に type(x) で解決されます。ここで理解できないのは最後のケースです: c.__getattribute__、オブジェクトにはメソッド __getattribute__ が含まれていません (そして C はオブジェクトから継承されます)。呼ばれた。
誰かがこれを説明できますか?? または、これに関するドキュメントがどこにあるのか教えてください。ありがとうございます。