簡體   English   中英

Python: __dict__ shows class attribute for the object of the class even when the behavior inside the __init__ mutates the class attribute

[英]Python: __dict__ shows class attribute for the object of the class even when the behavior inside the __init__ mutates the class attribute

據我了解,

對於像列表這樣的可變 object,如果底層 object 支持類似列表的突變,+=(增強分配)會導致 object 的突變。 當然,這不適用於不支持突變的不可變對象,因為__iadd__不存在,而__add__是被調用的對象。

考慮以下代碼:

class TestClass:
    bar = []

    def __init__(self, x):
        self.bar += [x]


f = TestClass(1)
g = TestClass(2)
h = TestClass(3)
print(f.bar)
print(g.bar)
print(TestClass.bar)

現在,我明白為什么所有三個 g,f,h 都會打印出[1, 2, 3]因為我們正在“改變” class 屬性。

但是當我嘗試通過print(f.__dict__)查看對象的命名空間時,我也看到了 object 中的 bar 屬性。

問題 1:如果實際發生突變的屬性是 class 屬性,為什么會在 object 命名空間中創建實例?

其次,“如果”該實例變量在對象中創建(如 f),那么f.bar += 4應該只影響 object f,因為 f 中的新實例變量 bar 應該遮蔽了 class 屬性。 但我看到依次執行f.bar+=4也會更新 class 屬性,這讓我完全困惑。

有人可以幫我嗎?

這可能有點微妙。 你可以想到

self.bar += [x]

相當於

self.bar = self.bar.__iadd__([x])

因此, self.bar.__iadd__([x])改變列表,本質上調用list.extend ,然后返回列表 object 此列表 object 與TestClass.bar引用的相同,已分配給實例屬性

所以現在你有一個與 class 屬性同名的實例屬性,並且兩者都綁定到同一個列表 object

這甚至在 [documentation] 中被警告:

對於屬性引用的目標, 關於 class 和實例屬性的相同警告適用於常規分配。

需要注意的是:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM