【问题标题】:Python __dict__Python __dict__
【发布时间】:2017-12-30 19:04:18
【问题描述】:

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

__module__
__dict__ 
__weakref__
__doc__

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    不,__dict__ 包含对象的动态属性。然而,这些并不是对象可以拥有的唯一属性,通常还会参考对象的 type 来查找属性。

    例如,类的方法也可以作为实例的属性找到。许多这样的属性是descriptor objects 并且在查找时与对象绑定。这是所有类继承自object__getattribute__ 方法的工作;对象上的属性通过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__),以及作为类实例描述符的其他类(__dict____weakref__)。后者必须添加到,因为类本身也有这些属性,取自type,再次作为描述符。

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

    【讨论】:

    • 非常感谢@Martijn 的回答。这很有帮助。
    • __bases__ is writeable (至少对于__doc__ 可写的相同类)。这是一个描述符,因为设置它需要额外的处理,而这在type.__setattr__ 中并不适合,并且因为实现将底层数据存储在类的内存布局中的专用插槽中而不是把它放在相关的字典中。
    猜你喜欢
    • 2011-06-20
    • 1970-01-01
    • 2012-05-16
    • 2011-04-07
    • 2014-04-05
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多