Pythonのdir()と__dict__の最大の違いは何ですか?
疑問点
class C(object):
def f(self):
print self.__dict__
print dir(self)
c = C()
c.f()
を出力します。
{}
['__class__', '__delattr__','f',....]
self.__dict__に'f'がないのはなぜか?
どのように解決するのですか?
dir()
は、検索するよりもはるかに多くの
__dict__
まず最初に
dir()
のような属性を使用する方法を知っている API メソッドです。
__dict__
を使ってオブジェクトの属性を調べる方法を知っている API メソッドです。
全てのオブジェクトに
__dict__
属性があるわけではありません。例えば、もしあなたが
__slots__
という属性があります。
をカスタムクラスに追加すると、そのクラスのインスタンスには
__dict__
属性はありませんが
dir()
はそれらのインスタンスで利用可能な属性をリストアップすることができます。
>>> class Foo(object):
... __slots__ = ('bar',)
... bar = 'spam'
...
>>> Foo().__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__dict__'
>>> dir(Foo())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar']
多くの組み込み型にも同じことが言えます。
list
には
__dict__
属性はありませんが、すべての属性をリストアップするには
dir()
:
>>> [].__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
何
dir()
はインスタンスに対して行う
Pythonのインスタンスは独自の
__dict__
を持ちますが、そのクラスも同じです。
>>> class Foo(object):
... bar = 'spam'
...
>>> Foo().__dict__
{}
>>> Foo.__dict__.items()
[('__dict__', <attribute '__dict__' of 'Foo' objects>), ('__weakref__', <attribute '__weakref__' of 'Foo' objects>), ('__module__', '__main__'), ('bar', 'spam'), ('__doc__', None)]
は
dir()
メソッドでは
と
これらの
__dict__
属性があります。
と
にあるものは
object
で、インスタンス、クラス、そしてそのクラスのすべての祖先で利用可能な属性の完全なリストを作成します。
クラスに属性を設定すると、インスタンスはこれらも見ることができます。
>>> f = Foo()
>>> f.ham
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'ham'
>>> Foo.ham = 'eggs'
>>> f.ham
'eggs'
というのは、この属性はクラス
__dict__
:
>>> Foo.__dict__['ham']
'eggs'
>>> f.__dict__
{}
インスタンス
__dict__
が空のままであることに注意してください。Pythonオブジェクトの属性検索は、インスタンスから型、親クラスへとオブジェクトの階層を辿って属性を検索していきます。
インスタンスに直接属性を設定したときだけ、その属性が反映された
__dict__
に反映され、インスタンスのクラス
__dict__
は変更されないままです。
>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False
TLDR;または要約
dir()
は単にオブジェクトの
__dict__
(を調べるだけでなく、オブジェクトの遺産(そのクラスまたは型、およびそのクラスまたは型のスーパークラスまたは親)を使用して、利用可能なすべての属性の全体像を提供します。
インスタンス
__dict__
はそのインスタンスの属性の 'ローカル' セットであり、インスタンスで利用可能なすべての属性を含んでいるわけではありません。代わりに、クラスとクラスの継承ツリーも見る必要があります。
関連
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] PandasでDataFrameの行を反復処理する方法
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] インスタンスのクラス名を取得する?
-
[解決済み] Pythonで型をチェックする標準的な方法は何ですか?
-
[解決済み] リストとタプルの違いは何ですか?
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み] PySparkでデータフレームのカラムをString型からDouble型に変更する方法は?
最新
-
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のマルチプロセッシングプールimap_unorderedの呼び出しの進捗を表示しますか?
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] Spyderを仮想環境で動作させるには?
-
[解決済み] dict を txt ファイルに書き、それを読み取る?
-
[解決済み] Python 2.7サポート終了?
-
[解決済み] SQLAlchemy - テーブルのリストを取得する
-
[解決済み] Pythonでファイルの読み込みと上書きをする
-
[解決済み] virtualenvsはどこに作成するのですか?
-
[解決済み] 新しいpip backtrackingの実行時問題の解決
-
[解決済み] Alembicアップグレードスクリプトでインサートやアップデートを実行するにはどうすればよいですか?