gpt4 book ai didi

python - Python 中 dir() 和 __dict__ 的最大区别是什么

转载 作者:IT老高 更新时间:2023-10-28 20:20:53 28 4
gpt4 key购买 nike

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

输出:

{}

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

为什么 self.__dict__ 中没有'f'

最佳答案

dir()不仅仅是查找 __dict__

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

并非所有对象都有 __dict__属性虽然。例如,如果您要添加 __slots__ attribute对于您的自定义类,该类的实例不会有 __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']

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

什么dir()使用实例

Python 实例有自己的 __dict__ ,但他们的类(class)也是如此:

>>> 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()方法使用 both 这些 __dict__属性, 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__中反射(reflect)的属性实例,而类 __dict__保持不变:

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

TLDR;或摘要

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

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

关于python - Python 中 dir() 和 __dict__ 的最大区别是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14361256/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com