【问题标题】:Making __dict__ A Property使 __dict__ 成为一个属性
【发布时间】:2017-12-31 18:21:55
【问题描述】:

为什么会这样:

class Bunch(dict):

    def __init__(self, *args, **kwargs):
        super(Bunch, self).__init__(*args, **kwargs)
        self.__dict__ = self

b = Bunch()
b["a"] = 1
print(b.a)

虽然是循环引用:

import sys
print(sys.getrefcount(b))
# ref count is 3 when normally it is 2

但不是这个:

class Bunch(dict):

    @property
    def __dict__(self):
        return self

b = Bunch()
b["a"] = 1
b.a

# raises AttributeError

虽然__dict__ 是大多数外观的属性,但在幕后实现了一些特殊行为,绕过了property 创建的描述符逻辑。

【问题讨论】:

  • 想想self.__dict__ = self。显然,这不能等同于self.__dict__['__dict__'] = self,对吧?所以self.__dict__ 一定很神奇。
  • @OferSadan:不,函数与否无关紧要,反正在第二个例子中它不是一个函数。

标签: python datamodel bunch


【解决方案1】:

默认的__dict__ 属性已经基本上 一个属性。 (不是字面意义上的property,而是通过描述符协议实现的,就像property一样。)

当您设置self.__dict__ = self 时,它会通过__dict__ 描述符的__set__ 方法并替换用于实例属性的字典。

但是,Python 在执行属性操作时不使用__dict__ 描述符来查找实例字典;它使用不同的内部机制。因此,创建您自己的__dict__ 描述符不会影响第二个示例中b.a 的属性查找机制。

【讨论】:

    猜你喜欢
    • 2011-06-20
    • 2020-12-09
    • 2013-11-23
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    相关资源
    最近更新 更多