我刚刚拥有。我无法相信这是真的,但经过测试,我发现它是:
class A(object):
v = []
a = A()
b = A()
您认为以下代码会返回什么?
a.v is b.v
此代码怎么样?
a.v.append(1)
a.v[0] == b.v[0]
果然,a.v is b.v
,他们都将相同的参考分享到相同的列表。来自一个,以及其他所有编程语言背景,这有什么意义?
在Java中,如果我要写一个这样的类:
class A {
public Object[] v = new Object[]{};
}
...在我最疯狂的梦想中,我绝不会认为该类的两个实例将共享相同的数组引用。
我的主要问题是,Python类中的初始值是否与Java,C#等相同?为什么类的所有实例都对同一个列表共享相同的引用?
答案 0 :(得分:13)
您已定义了类属性而不是实例属性。 Python正在做正确的事情。
而不是
class A(object):
v = [] # Class attribute, shared across all instances!
你需要
class A(object):
def __init__(self): # Instance attribute, created anew for each new object
self.v = []
答案 1 :(得分:3)
Java语法与Python不同。根据您的Java知识尝试猜测正确使用的东西并不是一个好主意
class A(object):
v = [] # class attribute
class A(object):
def __init__(self):
self.v = [] # instance attribute
好的,这些规则很有趣。
如果您尝试访问self.v
,首先Python查找实例属性,如果没有查看该类,然后是父类,直到找到一个或引发属性错误
当您分配到self.v
时,它始终会将其绑定到实例属性,即使它之前没有。
然后有描述符......
答案 2 :(得分:2)
那是因为v
是类属性(在C ++中认为是static
成员变量)。
如果您需要非共享成员属性,则必须在构造函数中声明它:
class A(object):
def __init__(self):
selv.v = []
答案 3 :(得分:1)
class A(object):
v = []
此处v
是一个类属性而非实例属性,它们仅在类定义期间定义一次。所以,这就是为什么他们指向同一个对象。
改为使用实例属性:
class A(object):
def __init__(self):
self.v = [] #different for each instance
a= A()
b = A()
print a is b #prints False