まず、と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']
質問になります;)私は自分自身を見るでしょう