Python __dict__

Python __dict__

属性 __dict__ 应该包含用户定义的属性。但是如果我们打印一个空 class 的 __dict__,我也会得到:

__module__
__dict__ 
__weakref__
__doc__

根据 class 对象类型在 __dict__ 属性中由 Python 预填充。

现在,__base____class__ 也是 Python 定义的 class 对象类型的属性,但不包含在 __dict__.[=20 中=]

是否有任何规则指定对象中包含哪些 dunder 属性 __dict__ 哪些不包含?

The attribute __dict__ is supposed to contain user defined attributes.

不,__dict__ 包含对象的动态属性。然而,对象的 类型 并不是唯一的属性,通常也会参考对象的类型 来查找属性。

例如,class 上的方法也可以作为实例的属性找到。许多这样的属性是 descriptor objects 并且在查找时 绑定 到对象。这是所有 class 继承自 object__getattribute__ 方法的工作;对象上的属性通过 type(object).__getattribute__(attribute_name) 解析,此时类型的描述符以及直接设置在对象上的属性(在 __dict__ 映射中)被考虑。

class的__bases__属性由class元类型提供,默认为type();它是一个描述符:

>>> class Foo:
...     pass
...
>>> Foo.__bases__
(<class 'object'>,)
>>> type.__dict__['__bases__']
<attribute '__bases__' of 'type' objects>
>>> type.__dict__['__bases__'].__get__(Foo, type)
(<class 'object'>,)

__dict__ 恰好是存储可以具有任何有效字符串名称的属性的地方。对于 classes,它包括在创建 class 时设置的几个标准属性(__module____doc__),以及其他作为 [=49 实例的描述符的=](__dict____weakref__)。后者必须添加到 class,因为 class 本身也有那些属性,取自 type,再次作为描述符。

那么为什么 __bases__ 是描述符,而 __doc__ 不是?您不能将 __bases__ 设置为任何值,因此描述符 setter 检查特定条件并且是重建内部缓存的机会。 Python 核心开发人员使用描述符来限制可以设置的内容,或者在设置值时需要额外的工作(例如验证和更新内部结构)。