Python __dict__

max*_*uas 4 python magic-methods python-3.x

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

__module__
__dict__ 
__weakref__
__doc__
Run Code Online (Sandbox Code Playgroud)

其中Python在__dict__属性中预先填充了类对象类型.

现在,__base__并且__class__也Python中定义的类的对象类型的属性,但不包括在__dict__.

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

Mar*_*ers 10

该属性__dict__应包含用户定义的属性.

不,它__dict__包含对象的动态属性.这些不是对象可以拥有的唯一属性,但通常也会查找对象的类型以查找属性.

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

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

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

__dict__恰好是存储可以具有任何有效字符串名称的属性的地方.对于包含在创建(__module____doc__)类时设置的几个标准属性的类,以及作为类(__dict____weakref__)实例的描述符的其他类.后者必须添加到类中,因为类本身也具有这些属性type,再次作为描述符.

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