75
class C(object):
    def f(self):
        print self.__dict__
        print dir(self)
c = C()
c.f()

出力:

{}

['__class__', '__delattr__','f',....]

self.__dict__ に「f」がない理由

4

3 に答える 3

141

dir()見上げる以上のことをする__dict__

まず第一に、オブジェクトの属性を検索するdir()ような属性の使用方法を知っている API メソッドです。__dict__

ただし、すべてのオブジェクトに__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']

同じことが多くの組み込み型にも当てはまります。lists には__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()メソッドは、これらの属性1 つの属性の両方を使用して、インスタンス、クラス、およびクラスのすべての祖先で使用可能な属性の完全なリストを作成します。__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__は、そのインスタンスの属性の「ローカル」セットにすぎず、インスタンスで使用可能なすべての属性が含まれているわけではありません。代わりに、クラスとクラスの継承ツリーも確認する必要があります。

于 2013-01-16T15:03:12.237 に答える
6

関数fは class の辞書に属しCます。 c.__dict__インスタンスに固有の属性を生成しますc

>>> class C(object):
    def f(self):
        print self.__dict__


>>> c = C()
>>> c.__dict__
{}
>>> c.a = 1
>>> c.__dict__
{'a': 1}

C.__dict__Cfunction を含むclass の属性を生成しますf

>>> C.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'C' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None, 'f': <function f at 0x0313C1F0>})

オブジェクトはそのクラス (および実際にはすべての祖先クラス) の属性を参照できますが、そのように参照されたクラス属性は、関連付けられたdict自体の一部にはなりません。fしたがって、クラスCasで定義された関数への正当なアクセスですが、 inc.f()の属性としては表示されません。cc.__dict__

>>> c.a = 1
>>> c.__dict__
{'a': 1}
于 2016-01-22T03:57:40.530 に答える