【问题标题】:Attribute access in Python: first slots, then __dict__?Python 中的属性访问:首先是插槽,然后是 __dict__?
【发布时间】:2013-02-14 20:27:30
【问题描述】:

在下面的示例中,即使x 存在于__dict__ 中,属性x 仍从对象的槽中访问(这不是典型的或可能有用的情况,但我很好奇):

>>> class C(object):
...     __slots__ = 'x'
...     
>>> class D(C):
...     pass
... 
>>> obj = D()
>>> obj.x = 'Stored in slots'
>>> obj.__dict__
{}
>>> obj.__dict__['x'] = 'stored in __dict__'
>>> obj.x
'Stored in slots'

这种访问顺序(插槽优先)是记录在案的行为吗?还是只是一个实现细节?

【问题讨论】:

    标签: python attributes slots


    【解决方案1】:

    是的,对象的__dict__ 仅在查询数据描述符后才会查询。 __slots__ 属性被实现为数据描述符。

    Invoking descriptors:

    对于实例绑定,描述符调用的优先级取决于定义的描述符方法。描述符可以定义__get__()__set__()__delete__() 的任意组合。如果它没有定义__get__(),那么访问该属性将返回描述符对象本身,除非对象的实例字典中有值。如果描述符定义了__set__()和/或__delete__(),它是一个数据描述符;如果两者都没有定义,则它是非数据描述符。通常,数据描述符定义__get__()__set__(),而非数据描述符只有__get__() 方法。定义了__set__()__get__() 的数据描述符始终覆盖实例字典中的重新定义。相反,非数据描述符可以被实例覆盖。

    并且来自同一页面,section on slots:

    __slots__ 在类级别通过为每个变量名创建描述符(实现描述符)来实现。因此,类属性不能用于为__slots__定义的实例变量设置默认值;否则,类属性将覆盖描述符分配。

    【讨论】:

    • 我相信这也应该被引用(来自Implementing Descriptors):“描述符必须在所有者的类字典或其父类字典中”。
    • @PavelAnossov:不确定这对理解槽有什么帮助。插槽属性作为类上的描述符实现,数据描述符位于实例__dict__ 值之前。这足以记录这种行为,不是吗?
    • @PavelAnossov:是的,有时人们对在哪里查找描述符感到困惑,但这不是问题。
    猜你喜欢
    • 2011-06-20
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2023-04-05
    相关资源
    最近更新 更多