1

我刚拥有。我不敢相信这是真的,但经过测试,我发现它是:

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# 等中的初始值等价?为什么类的所有实例共享对同一个列表的相同引用?

4

4 回答 4

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 = []
于 2013-05-14T06:13:55.870 回答
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它时,即使它以前没有,也总是将它绑定到实例属性。

然后是描述符...

于 2013-05-14T06:14:17.543 回答
2

那是因为v它是一个属性(想想staticC++ 中的成员变量)。

如果你想要一个非共享的成员属性,你必须在构造函数中声明它:

class A(object):
    def __init__(self):
        selv.v = []
于 2013-05-14T06:15:10.410 回答
1
class A(object):
    v = []

v是一个类属性而不是实例属性,它们只在类定义期间定义一次。所以,这就是为什么 the're 指向同一个对象。

改用实例属性:

class A(object):
    def __init__(self):
        self.v = []     #different for each instance
a= A()
b = A()
print a is b  #prints False
于 2013-05-14T06:14:16.703 回答