![](/img/trans.png)
[英]How to add attributes to a class in __init__() of the class with __dict__ in Python 3?
[英]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.