class C(object): def f(self): print self.__dict__ print dir(self) c = C() c.f()
输出:
{} ['__class__', '__delattr__','f',....]
为什么自我中不存在“ f”。dict
dir()
__dict__
首先,dir()是一种API方法,它知道如何使用属性__dict__来查找对象的属性。
但是,并非所有对象都具有__dict__属性。例如,如果要向自定义类添加__slots__属性,则该类的实例将没有__dict__属性,但dir()仍可以列出这些实例上的可用属性:
__slots__
>>> 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():
list
>>> [].__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']
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上创建实例,类可用属性的完整列表,并在类的所有祖先。
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
dir()不仅查找对象__dict__(有时甚至不存在),它还将使用对象的遗产(其类或类型,以及该类或类型的任何超类或父级)为您提供完整的图像所有可用的属性。
实例__dict__只是该实例上的“本地”属性集,并不包含该实例上可用的每个属性。相反,您还需要查看类和类的继承树。