[解決済み] Pythonのクラスの__dict__.__dict__属性とは何ですか?
質問
>>> class A(object): pass
...
>>> A.__dict__
<dictproxy object at 0x173ef30>
>>> A.__dict__.__dict__
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
AttributeError: 'dictproxy' object has no attribute '__dict__'
>>> A.__dict__.copy()
{'__dict__': <attribute '__dict__' of 'A' objects> ... }
>>> A.__dict__['__dict__']
<attribute '__dict__' of 'A' objects> # What is this object?
もし私が
A.something = 10
とすると、これは
A.__dict__
. 何
は
この
<attribute '__dict__' of 'A' objects>
で見つかった
A.__dict__.__dict__
は、いつ、どのようなものを含むのでしょうか?
どのように解決するのですか?
まずはじめに
A.__dict__.__dict__
とは異なり
A.__dict__['__dict__']
. 前者は存在せず、後者は
__dict__
の属性は、そのクラスのインスタンスが持っているはずのものです。これはデータ記述子オブジェクトで、特定のインスタンスの属性の内部辞書を返します。要するに
__dict__
属性は、オブジェクトの
__dict__
に格納できないため、クラスで定義された記述子を介してアクセスすることになります。
これを理解するためには 記述子プロトコルのドキュメント .
短いバージョンです。
-
インスタンスの場合
a
クラスのA
へのアクセスはa.__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__
記述子は、この辞書へのアクセスを実装しています。
-
a.name
は、これらを順番に試すことと同じです。type(a).__dict__['name'].__get__(a, type(a))
(ただしtype(a).__dict__['name']
が データ ディスクリプタ)。a.__dict__['name']
,type(a).__dict__['name'].__get__(a, type(a))
,type(a).__dict__['name']
. -
a.__dict__
も同じですが、明らかな理由で二番目のステップをスキップします。
は不可能なので
__dict__
をそれ自身に格納することは不可能なので、代わりに記述子プロトコルを介して直接アクセスし、インスタンスの特別なフィールドに格納されます。
同様のシナリオはクラスにも当てはまりますが、彼らの
__dict__
は特別なプロキシオブジェクトで、辞書のふりをし (しかし内部的にはそうではないかもしれません)、それを変更したり別のものに置き換えたりすることは許可されていません。このプロキシによって、とりわけ、クラスに固有で、そのベースの 1 つで定義されていないクラスの属性にアクセスすることができます。
デフォルトでは
vars(cls)
は3つの記述子を持ちます。
__dict__
インスタンスの属性を格納するためのものです。
__weakref__
で内部的に使用される
weakref
と
__doc__
は、クラスのdocstringです。を定義すると、最初の二つは消えてしまうかもしれません。
__slots__
. そうすると
__dict__
と
__weakref__
属性を使用する代わりに、各スロットに 1 つのクラス属性を設定します。インスタンスの属性は辞書に保存されず、クラス内のそれぞれの記述子によってアクセスすることになります。
そして最後に、矛盾しているのは
A.__dict__
とは異なる
A.__dict__['__dict__']
は、属性
__dict__
は、例外的に
は決して
で検索されます。
vars(A)
というように、この属性に当てはまることは、実質的に他のどの属性にも当てはまらないのです。例えば
A.__weakref__
は
A.__dict__['__weakref__']
. この矛盾がなければ
A.__dict__
を使ってもうまくいかないでしょうし、常に
vars(A)
を使用しなければなりません。
関連
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] Pythonで静的なクラス変数は可能ですか?
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み】if __name__ == "__main__": は何をするのでしょうか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] Pythonのインスタンス変数とクラス変数
-
[解決済み] 文字列から先頭と末尾のスペースを削除するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonです。未束縛のメソッドを束縛する?
-
[解決済み] pandasのDataFrameから空のセルを含む行を削除する
-
[解決済み] Python 2.7サポート終了?
-
[解決済み] SQLAlchemy - テーブルのリストを取得する
-
[解決済み] pandasのタイムゾーンに対応したDateTimeIndexを、特定のタイムゾーンに対応したナイーブなタイムスタンプに変換する。
-
[解決済み] matplotlib でプロットの軸、目盛、ラベルの色を変更する方法
-
[解決済み] Pandasを使って、既存のExcelファイルに新しいシートを保存する方法は?
-
[解決済み] Flaskで非同期タスクを作る
-
[解決済み] virtualenv の `--no-site-packages` オプションを元に戻す。
-
[解決済み] Pythonでリストが空かどうかをチェックする方法は?重複