2017-12-29 27 views
4

属性__dict__には、ユーザー定義の属性が含まれています。私たちは空のクラスの__dict__を印刷する場合でも、私もなるだろう:Python __dict__

クラスオブジェクトの型に応じて __dict__属性にPythonがあらかじめ入力されている
__module__ 
__dict__ 
__weakref__ 
__doc__ 

__base____class__は、クラスオブジェクトタイプのPython定義属性ですが、__dict__には含まれていません。

どのダンダー属性がオブジェクト__dict__に含まれているかを指定するルールはありますか?

答えて

9

属性__dict__には、ユーザー定義の属性が含まれています。

いいえ、__dict__動的属性オブジェクトのを含有します。オブジェクトが持つことができる唯一の属性ではありませんが、オブジェクトのタイプも通常は属性を検索するために参照されます。

たとえば、クラスのメソッドはインスタンスの属性としても見つかります。そのような属性の多くは、descriptor objectsであり、参照するとオブジェクトにがバインドされたです。これはすべてのクラスがobjectから継承する__getattribute__メソッドの仕事です。オブジェクトの属性はtype(object).__getattribute__(attribute_name)で解決されます。その時点で、オブジェクト上に直接設定された属性と同様に、型の記述子が考慮されます(__dict__マッピング内)。

クラスの__bases__属性は、クラスメタタイプ(デフォルトでtype())によって提供されます。

>>> class Foo: 
...  pass 
... 
>>> Foo.__bases__ 
(<class 'object'>,) 
>>> type.__dict__['__bases__'] 
<attribute '__bases__' of 'type' objects> 
>>> type.__dict__['__bases__'].__get__(Foo, type) 
(<class 'object'>,) 

__dict__だけで任意の有効な文字列名を持つことができる属性を格納する場所であることを起こる:それは記述です。クラスの作成時に設定されるいくつかの標準属性(__module__および__doc__)を含むクラス、およびクラスのインスタンスの記述子として存在するその他のクラス(__dict__および__weakref__)。後者はクラスに追加する必要があります。クラス自体にもtypeから取得した属性が記述子として存在するためです。

__bases__はなぜ記述子ですか、なぜ__doc__ではありませんか? __bases__には何も設定できないため、ディスクリプタ設定ツールは特定の条件をチェックし、内部キャッシュを再構築する機会です。 Pythonのコア開発者は、記述子を使用して、設定可能なものを制限したり、値を設定する際に追加作業(検証や内部構造の更新など)が必要な場合に使用します。

+0

ご回答ありがとうございます@Martijn。とても役に立ちました。 –

+0

['__bases__'は書き込み可能です](https://ideone.com/Qv2EHe)(少なくとも、' __doc__'は書き込み可能です)。これは記述子なので、 'type .__ setattr__'にはうまく収まらない余分な処理が必要となるため、クラスのメモリレイアウトの専用スロットに基底のデータを格納する方が便利です(さらに効率的です)それを関連する辞書に入れるのではなく。 – user2357112

+0

@ user2357112:はい、もちろん、言い回しを更新しました。 –

関連する問題