[英]Difference between dir(…) and vars(…).keys() in Python?
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... :) (我希望有区别,否则这会打破“一种方法”的原则...... :)
Python objects usually store their instance variables in a dictionary that belongs to the object (except for slots). Python 对象通常将它们的实例变量存储在属于该对象的字典中(槽除外)。
vars(x)
returns this dictionary (as does x.__dict__
). vars(x)
返回这个字典(和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."另一方面,
dir(x)
返回一个包含x
的“属性、其类的属性,并递归地返回其类的基类的属性”的字典。
When you access an object's attribute using the dot operator, Python does a lot more than just look up the attribute in that objects dictionary.当您使用点运算符访问对象的属性时,Python 所做的不仅仅是在该对象字典中查找属性。 A common case is when
x
is an instance of class C
and you call its method m
:一个常见的情况是当
x
是类C
一个实例并且你调用它的方法m
:
class C:
def m(self):
print("m")
x = C()
x.m()
The method m
is not stored in x.__dict__
.方法
m
不存储在x.__dict__
。 It is an attribute of the class C
.它是类
C
一个属性。
When you call xm()
, Python will begin by looking for m
in x.__dict__
, but it won't find it.当您调用
xm()
,Python 将首先在x.__dict__
m
,但它不会找到它。 However, it knows that x
is an instance of C
, so it will next look in C.__dict__
, find it there, and call m
with x
as the first argument.然而,它知道
x
是C
一个实例,所以它接下来会在C.__dict__
,在那里找到它,并以x
作为第一个参数调用m
。
So the difference between vars(x)
and dir(x)
is that dir(x)
does the extra work of looking in x
's class (and itsbases ) for attributes that are accessible from it, not just those attributes that are stored in x
's own symbol table.所以
vars(x)
和dir(x)
之间的区别在于dir(x)
做了额外的工作,在x
的类(及其基类)中查找可从中访问的属性,而不仅仅是那些存储的属性在x
自己的符号表中。 In the above example, vars(x)
returns an empty dictionary, because x
has no instance variables.在上面的例子中,
vars(x)
返回一个空字典,因为x
没有实例变量。 However, dir(x)
returns但是,
dir(x)
返回
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'm']
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 (grouped for easier reading):如果您没有看到差异,也许这会向您展示更多信息(分组以便于阅读):
>>> dir(list)
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__',
'__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__',
'__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend',
'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> vars(list).keys()
dict_keys(['__repr__',
'__hash__',
'__getattribute__',
'__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
'__iter__',
'__init__',
'__len__',
'__getitem__', '__setitem__', '__delitem__',
'__add__', '__mul__', '__rmul__', '__contains__', '__iadd__', '__imul__',
'__new__',
'__reversed__', '__sizeof__',
'clear', 'copy', 'append', 'insert', 'extend', 'pop', 'remove', 'index', 'count', 'reverse', 'sort',
'__class_getitem__',
'__doc__'])
If you don't feel like reading through that, dir
includes these attributes while vars
does not:如果您不想通读,
dir
包含这些属性,而vars
不包含:
>>> set(dir(list)) - vars(list).keys()
{'__class__', '__delattr__', '__dir__', '__format__', '__init_subclass__',
'__reduce__', '__reduce_ex__', '__setattr__', '__str__', '__subclasshook__'}
Note also that dir()
's output is sorted alphabetically, whereas vars()
's output is sorted by the order the attributes were defined in.另请注意,
dir()
的输出按字母顺序排序,而vars()
的输出按属性定义的顺序排序。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.