Terrifying initial values - mutable types share same reference?
本问题已经有最佳答案,请猛点这里访问。
我刚被拥有。我不敢相信这是真的,但经过测试,我发现它是:
1 2 3 4 5 | class A(object): v = [] a = A() b = A() |
您认为下面的代码将返回什么?
1 | a.v is b.v |
这个代码怎么办?
1 2 | a.v.append(1) a.v[0] == b.v[0] |
可以肯定的是,
在Java中,如果我要写一个这样的类:
1 2 3 | class A { public Object[] v = new Object[]{}; } |
…在我最疯狂的梦中,我永远不会想到类的两个实例将共享对数组的相同引用。
我的主要问题是,Python类中的初始值是否等同于爪哇、C等?为什么类的所有实例都共享对同一列表的相同引用?
您定义了类属性而不是实例属性。Python做得对。
而不是
1 2 | class A(object): v = [] # Class attribute, shared across all instances! |
你需要
1 2 3 | class A(object): def __init__(self): # Instance attribute, created anew for each new object self.v = [] |
Java语法与Python不同。试着根据Java知识尝试使用正确的方法不是一个好主意。
1 2 3 4 5 6 7 | class A(object): v = [] # class attribute class A(object): def __init__(self): self.v = [] # instance attribute |
好吧,规则有点滑稽。
如果尝试访问
当您分配给
还有描述符…
这是因为EDOCX1×0是一个类属性(在C++中考虑EDCOX1×4的成员变量)。
如果需要非共享成员属性,则必须在构造函数中声明它:
1 2 3 | class A(object): def __init__(self): selv.v = [] |
1 2 | class A(object): v = [] |
在这里,
改为使用实例属性:
1 2 3 4 5 6 | class A(object): def __init__(self): self.v = [] #different for each instance a= A() b = A() print a is b #prints False |