属性__dict__
应该包含用户定义的属性。但是如果我们打印一个空类的__dict__
,我也会得到:
__module__
__dict__
__weakref__
__doc__
相应于类对象类型,Python在__dict__
属性中预先填充了哪些。
现在,__base__
和__class__
也是类对象类型的Python定义属性,但未包含在__dict__
中。
是否有任何规则指定对象__dict__
中包含哪个dunder属性,哪些不属于?
答案 0 :(得分:9)
属性
__dict__
应该包含用户定义的属性。
不,__dict__
包含对象的动态属性。这些不是对象可以拥有的唯一属性,但是,通常也会查询对象的类型来查找属性。
例如,类上的方法也可以作为实例的属性找到。许多此类属性为descriptor objects,并且在查找时绑定到对象。这是所有类继承自__getattribute__
的{{1}}方法的工作;通过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'>,)
恰好是存储可以具有任何有效字符串名称的属性的地方。对于包含在创建类时设置的几个标准属性的类(__dict__
和__module__
),以及其他作为类实例(__doc__
和{{1}的描述符的类})。后者必须添加到类中,因为类本身也具有这些属性,取自__dict__
,再次作为描述符。
为什么__weakref__
是描述符,但type
不是?您无法将__bases__
设置为任何内容,因此描述符设置器会检查特定条件,并且是重建内部缓存的机会。 Python核心开发人员使用描述符来限制可以设置的内容,或者在设置值时需要额外的工作(如验证和更新内部结构)。