Python __dict __

时间:2017-12-29 22:47:12

标签: python python-3.x magic-methods

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

__module__
__dict__ 
__weakref__
__doc__

相应于类对象类型,Python在__dict__属性中预先填充了哪些。

现在,__base____class__也是类对象类型的Python定义属性,但未包含在__dict__中。

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

1 个答案:

答案 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核心开发人员使用描述符来限制可以设置的内容,或者在设置值时需要额外的工作(如验证和更新内部结构)。