Python 使之成为财产

Python 使之成为财产,python,datamodel,bunch,Python,Datamodel,Bunch,为什么这样做有效: 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

为什么这样做有效:

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

虽然从外观上看,
\uuuuuu dict\uuuuuu
是一个属性,但是在幕后实现了一些特殊的行为,绕过了由
属性创建的描述符逻辑,默认的
\uuuuuu
属性基本上已经是一个属性。(它不是字面上的
属性
,而是通过描述符协议实现的,就像
属性

当您设置
self.\uuuuu dict\uuuu=self
时,将通过
\uuuu dict\uuuu
描述符的
\uuuu set\uuuu
方法替换用于实例属性的dict


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

想想
self.\u dict\u=self
。显然,这不能等同于self,对吗?所以,
self.\uuuuu dict\uuuuu
一定很神奇。@OferSadan:不,函数与否无关紧要,在第二个例子中它也不是一个函数。