2017-07-25 81 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的屬性查找機制。