dir(object)返回的属性中没有__dict__这个属性,但是 object.__dict__却可以调用,不懂,希望高手解答。

2016-07-05 15:14:47 +08:00
 sudo987
如题。
已懂知识点:
1. __dict__只会返回“本地”属性, type 中的, bases 中的属性都不会返回。
2. dir()返回的属性要比__dict__多,因为, dir()会返回包括自身在内的属性+类型中的属性+所有基类中的属性。
2697 次点击
所在节点    Python
10 条回复
zeayes
2016-07-05 15:37:17 +08:00
sudo987
2016-07-05 17:00:59 +08:00
@zeayes 跟我的问题有关系么,请问。
cxyfreedom
2016-07-05 17:23:41 +08:00
https://docs.python.org/3.5/library/stdtypes.html#object.__dict__

文档中是这么解释的:
Special Attributes

The implementation adds a few special read-only attributes to several object types, where they are relevant. Some of these are not reported by the dir() built-in function

不知道这个解释行不行
======================================
开始看完你的问题,我自己都怀疑自己是不是会 python 了...
lonelinsky
2016-07-05 17:25:23 +08:00
lz 的 object 是什么样的? 我在 python3.4 下,无论是直接对 类 还是对 对象 调用 dir 里面都是有__dict__这个属性的…
lowzoom
2016-07-05 17:31:38 +08:00
Note: Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.

摘自官方文档,请注意最后一句。
sudo987
2016-07-05 17:43:33 +08:00
@lowzoom +1,我是该有为题多看看文档。
sudo987
2016-07-05 17:45:49 +08:00
答案在 5 楼。(注:我的版本是 2.7 )
sudo987
2016-07-05 17:48:48 +08:00
@lonelinsky 就是 dir(object),之前在 2.7 下遇到的问题,发帖上来,刚才我试了下 3.5 的, dir(object)也还是没有__dict__这个属性。
yufpga
2016-07-05 19:07:40 +08:00
然而, 实际上在 2.7 版本中__dict__是会返回其基类中的属性的
lonelinsky
2016-07-05 19:10:30 +08:00
@sudo987 我一开始理解为随便 new 出来一个 object 了,后来才发现是说 object 本身。

这个问题其实有点好玩,__dict__属性的存在按照上面的文档无需赘述,而按照 dir 的文档,如果调用的参数是有__dir__函数的话,是会调用参数的__dir__函数的,在 interactive 中测试下就会发现 object 本身是有__dir__函数的,尝试调用这个函数会发现需要传参,如果我们传入 object 作为参数,看到的结果里面就会有__dict__了,如下:
In [33]: object.__dir__(object)
Out[33]:
['__hash__',
'__instancecheck__',
'__subclasshook__',
'__module__',
'__class__',
'__setattr__',
'__reduce__',
'__ne__',
'__str__',
'__new__',
'__text_signature__',
'__basicsize__',
'__repr__',
'__ge__',
'__weakrefoffset__',
'__call__',
'__abstractmethods__',
'__dictoffset__',
'__le__',
'__getattribute__',
'__lt__',
'__format__',
'__name__',
'__itemsize__',
'__sizeof__',
'mro',
'__bases__',
'__qualname__',
'__reduce_ex__',
'__flags__',
'__dir__',
'__dict__',
'__init__',
'__subclasscheck__',
'__doc__',
'__subclasses__',
'__eq__',
'__mro__',
'__delattr__',
'__prepare__',
'__gt__',
'__base__']

而如果我们传入 None 作为参数,结果就和 dir(object)的结果几乎一样了,但是多了一个__bool__而且是不能调用的,如下:
In [34]: object.__dir__(None)
Out[34]:
['__hash__',
'__class__',
'__subclasshook__',
'__format__',
'__eq__',
'__reduce__',
'__bool__',
'__new__',
'__repr__',
'__gt__',
'__le__',
'__setattr__',
'__lt__',
'__str__',
'__sizeof__',
'__getattribute__',
'__ne__',
'__doc__',
'__init__',
'__ge__',
'__reduce_ex__',
'__delattr__',
'__dir__']

查看 python 的源码也可以发现,默认确实是传入 None 的。( https://hg.python.org/cpython/file/3.5/Objects/object.c +1326)

更具体的估计要跟 object 的实现代码才可以看出来了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/290411

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX