python中dir和__dict__最大的区别是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14361256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:11:35  来源:igfitidea点击:

what's the biggest difference between dir and __dict__ in python

pythonintrospection

提问by shellfly

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

output:

输出:

{}

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

why there is not a 'f' in self.__dict__

为什么 self.__dict__ 中没有“f”

采纳答案by Martijn Pieters

dir()does much more than look up __dict__

dir()不仅仅是查找 __dict__

First of all, dir()is a API method that knows how to use attributes like __dict__to look up attributes of an object.

首先dir()是一个 API 方法,它知道如何使用属性,例如__dict__查找对象的属性。

Not all objects have a __dict__attribute though. For example, if you were to add a __slots__attributeto your custom class, instances of that class won't have a __dict__attribute, yet dir()can still list the available attributes on those instances:

不过,并非所有对象都有__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']

The same applies to many built-in types; lists do not have a __dict__attribute, but you can still list all the attributes using dir():

这同样适用于许多内置类型;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']

What dir()does with instances

dir()实例有什么作用

Python instances have their own __dict__, but so does their class:

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)]

The dir()method uses boththese __dict__attributes, andthe one on objectto create a complete list of available attributes on the instance, the class, and on all ancestors of the class.

dir()方法使用两个__dict__属性,object实例、类和类的所有祖先上创建可用属性的完整列表。

When you set attributes on a class, instances see these too:

在类上设置属性时,实例也会看到这些:

>>> 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'

because the attribute is added to the class __dict__:

因为该属性已添加到类中__dict__

>>> Foo.__dict__['ham']
'eggs'
>>> f.__dict__
{}

Note how the instance __dict__is left empty. Attribute lookup on Python objects follows the hierarchy of objects from instance to type to parent classes to search for attributes.

请注意实例如何__dict__留空。Python 对象的属性查找遵循对象的层次结构,从实例到类型再到父类以搜索属性。

Only when you set attributes directly on the instance, will you see the attribute reflected in the __dict__of the instance, while the class __dict__is left unchanged:

只有直接在实例上设置属性时,才会看到实例的属性体现出来__dict__,而类__dict__保持不变:

>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False

TLDR; or the summary

TLDR;或总结

dir()doesn't just look up an object's __dict__(which sometimes doesn't even exist), it will use the object's heritage (its class or type, and any superclasses, or parents, of that class or type) to give you a complete picture of all available attributes.

dir()不只是查找对象的__dict__(有时甚至不存在),它会使用对象的遗产(它的类或类型,以及该类或类型的任何超类或父类)为您提供完整的图片所有可用的属性。

An instance __dict__is just the 'local' set of attributes on that instance, and does not contain every attribute available on the instance. Instead, you need to look at the class and the class's inheritance tree too.

实例__dict__只是该实例上的“本地”属性集,并不包含实例上可用的所有属性。相反,您还需要查看类和类的继承树。

回答by Naveen Kumar

The function fbelongs to the dictionary of class C. c.__dict__yields attributes specific to the instance c.

该函数f属于 class 的字典Cc.__dict__产生特定于实例的属性c

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


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

C.__dict__would yield attributes of class C, including function f.

C.__dict__将产生类的属性C,包括函数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>})

While an object can refer to an attribute of its class (and indeed all the ancestor classes), the class attribute so referred does not become part of the associated dictitself. Thus while it is legitimate access to function fdefined in class Cas c.f(), it does not appear as an attribute of cin c.__dict__.

虽然一个对象可以引用它的类的一个属性(实际上是所有的祖先类),但这样引用的类属性不会成为相关字典本身的一部分。因此,虽然它是f对类Cas 中定义的函数的合法访问c.f(),但它不会作为cin的属性出现c.__dict__

>>> c.a = 1
>>> c.__dict__
{'a': 1}