まず、とA.__dict__.__dict__は異なりA.__dict__['__dict__']、前者は存在しません。後者は、__dict__クラスのインスタンスが持つ属性です。これは、特定のインスタンスの属性の内部ディクショナリを返す記述子オブジェクトです。つまり、__dict__オブジェクトの属性はオブジェクトの__dict__に格納できないため、クラスで定義された記述子を介してアクセスされます。
これを理解するには、記述子プロトコルのドキュメントを読む必要があります。
ショートバージョン:
- クラスのインスタンスでは
A、へのアクセスinstance.__dict__が提供さA.__dict__['__dict__']れvars(A)['__dict__']ます。これはと同じです。
- クラスAの場合、へのアクセス
A.__dict__はtype.__dict__['__dict__'](理論的には)によって提供され、と同じvars(type)['__dict__']です。
長いバージョン:
クラスとオブジェクトはどちらも、(クラスまたはメタクラスのを介して実装された)属性演算子__getattribute__と、__dict__が使用する属性/プロトコルの両方を介して属性へのアクセスを提供しますvars(ob)。
通常のオブジェクトの場合、__dict__オブジェクトはdict属性を格納する別のオブジェクトを作成し、__getattribute__最初にそのオブジェクトにアクセスしてそこから属性を取得しようとします(記述子プロトコルを使用してクラス内の属性を検索する前、およびを呼び出す前__getattr__)。__dict__クラスの記述子は、この辞書へのアクセスを実装します。
x.nameオーダーのものを試すと同等です:x.__dict__['name']、type(x).name.__get__(x, type(x))、type(x).name
x.__dict__ 同じことをしますが、明白な理由で最初のものをスキップします
をインスタンスに格納すること__dict__は不可能であるため、代わりに記述子プロトコルを介して直接アクセスされ、インスタンスの特別なフィールドに格納されます。instance__dict__
同様のシナリオがクラスにも当てはまりますが、それら__dict__は辞書のふりをしている(ただし内部的にはない可能性があります)特別なプロキシオブジェクトであり、変更したり、別のオブジェクトに置き換えたりすることはできません。このプロキシを使用すると、とりわけ、クラスのいずれかのベースで定義されていない、そのクラスに固有の属性にアクセスできます。
デフォルトでvars(cls)は、空のクラスのは3つの記述子__dict__を保持します- __weakref__によって内部的に使用されるインスタンスの属性とweakrefクラスのdocstring を格納するためです。定義すると、最初の2つはなくなる可能性があります__slots__。次に__dict__、__weakref__属性はありませんが、代わりに各スロットに単一のクラス属性があります。その場合、インスタンスの属性はディクショナリに格納されず、それらへのアクセスはクラスのそれぞれの記述子によって提供されます。
最後に、とA.__dict__は異なる不整合はA.__dict__['__dict__']、属性__dict__が例外的にで検索されないvars(A)ためです。そのため、これに当てはまることは、使用する他のどの属性にも当てはまりません。たとえば、A.__weakref__はと同じですA.__dict__['__weakref__']。この不整合が存在しなかった場合、使用A.__dict__は機能せず、vars(A)代わりに常に使用する必要があります。
ive。少なくとも、これはこれ以上のA.__dict__['ive']質問になります;)私は自分自身を見るでしょう