2017-07-25 26 views
1

为什么这项工作:制作__dict__ A楼盘

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创建。

+0

想想'self .__ dict__ = self'。显然,*不能等同于'self .__ dict __ ['__ dict__'] = self',对吗?所以'self .__ dict__'一定是神奇的。 – Kevin

+0

@OferSadan:不,功能与否无关紧要,无论如何它不是第二个例子中的功能。 – user2357112

回答

2

默认__dict__属性已经基本属性。 (这不是字面上property,但它通过描述协议的实现,就像property

当你设置self.__dict__ = self,即穿过__dict__描述符的__set__方法,取代用于实例属性的字典。

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