Python 中 dir(...) 和 vars(...).keys() 的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/980249/
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-11-03 21:12:01  来源:igfitidea点击:

Difference between dir(…) and vars(…).keys() in Python?

python

提问by Eric O Lebigot

Is there a difference between dir(…)and vars(…).keys()in Python?

Python 中dir(…)和之间有区别vars(…).keys()吗?

(I hope there is a difference, because otherwise this would break the "one way to do it" principle... :)

(我希望有区别,否则这会打破“一种方法”的原则...... :)

回答by M.J.

Python objects store their instance variables in a dictionary that belongs to the object. vars(x)returns this dictionary (as does x.__dict__). dir(x), on the other hand, returns a dictionary of x's "attributes, its class's attributes, and recursively the attributes of its class's base classes."

Python 对象将它们的实例变量存储在属于该对象的字典中。vars(x)返回此字典(与 一样x.__dict__)。dir(x),另一方面,返回一个包含x“属性、其类的属性,并递归地返回其类的基类的属性”的字典。

When you access an object's attribute using the dot operator, python does a lot more than just looking up the attribute in that objects dictionary. A common case is when xis an object of class Cand you call a method mon it.

当您使用点运算符访问对象的属性时,python 所做的不仅仅是在该对象字典中查找属性。一个常见的情况是 whenx是一个类的对象C并且你m在它上面调用一个方法。

class C(object):
    def m(self):
        print "m"

x = C()
x.m()

The method mis not stored in x.__dict__. It is an attribute of the class C. When you call x.m(), python will begin by looking for m in x.__dict__, but it won't find it. However, it knows that xis an instance of C, so it will next look in C.__dict__, find it there, and call mwith xas the first argument.

该方法m不存储在x.__dict__. 它是类的一个属性C。当您调用 时x.m(),python 将首先在中查找 m x.__dict__,但它不会找到它。然而,它知道那x是 的一个实例C,所以它接下来会在C.__dict__中查找,在那里找到它,并将mwithx作为第一个参数调用。

So the difference between vars(x)and dir(x)is that dir(x)does the extra work of looking in x's class (and its bases) for attributes that are accessible from it, not just those attributes that are stored in x's own symbol table. In the above example, vars(x)returns an empty dictionary, because xhas no instance variables. However, dir(x)returns

所以vars(x)and之间的区别在于,dir(x)dir(x)做了额外的工作,即在x的类(及其基类)中查找可从它访问的属性,而不仅仅是那些存储在它x自己的符号表中的属性。在上面的例子中,vars(x)返回一个空字典,因为x没有实例变量。然而,dir(x)返回

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'm']

回答by Paolo Bergantino

The documentation has this to say about dir:

文档有这样的说法dir

Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.

不带参数,返回当前本地范围内的名称列表。使用参数,尝试返回该对象的有效属性列表。

And this about vars:

这关于vars

Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a __dict__attribute), returns a dictionary corresponding to the object's symbol table.

不带参数,返回与当前本地符号表对应的字典。使用模块、类或类实例对象作为参数(或任何其他具有__dict__属性的东西),返回对应于对象符号表的字典。

If you don't see the difference, maybe this will show you more:

如果你没有看到差异,也许这会告诉你更多:

>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delsli
ce__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getit
em__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__r
educe__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__'
, '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'a
ppend', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'
]
>>> vars(list).keys()
['__getslice__', '__getattribute__', 'pop', 'remove', '__rmul__', '__lt__', '__s
izeof__', '__init__', 'count', 'index', '__delslice__', '__new__', '__contains__
', 'append', '__doc__', '__len__', '__mul__', 'sort', '__ne__', '__getitem__', '
insert', '__setitem__', '__add__', '__gt__', '__eq__', 'reverse', 'extend', '__d
elitem__', '__reversed__', '__imul__', '__setslice__', '__iter__', '__iadd__', '
__le__', '__repr__', '__hash__', '__ge__']

If you don't feel like reading through that, dirincludes these attributes while varsdoes not:

如果您不想通读,请dir包含这些属性,而vars不要包含这些属性:

>>> set(dir(list)).difference(vars(list).keys())
set(['__str__', '__reduce__', '__subclasshook__', '__setattr__', '__reduce_ex__'
, '__format__', '__class__', '__delattr__'])

回答by Mangu Singh Rajpurohit

Apart from Answers given, I would like to add that, using vars() with instances built-in types will give error, as instances builtin types do not have __dict__attribute.

除了给出的答案之外,我想补充一点,将 vars() 与实例内置类型一起使用会出错,因为实例内置类型没有__dict__属性。

eg.

例如。

In [96]: vars([])
---------------------------------------------------------------------------

TypeError Traceback (most recent call last)
<ipython-input-96-a6cdd8d17b23> in <module>()
      ----> 1 vars([])
TypeError: vars() argument must have __dict__ attribute