[英]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.