1

这应该很简单...

class Object:
    x = 0
    y = []

a = Object()
b = Object()

a.x = 1
b.x = 2
print a.x, b.x
# output: 1 2
# works as expected

a.y.append(3)
b.y.append(4)
print a.y, b.y
# output: [3, 4] [3, 4]
# same list is referenced  how to fix?
# desired output: [3] [4]

据我所知,a.yb.y引用相同的列表。我怎样才能让他们分开?最好不添加__init__方法。

4

4 回答 4

3

y当您定义类时,您只创建一次的值。要为 的每个实例分配不同的列表y,您确实需要一个 init 函数。只需放入self.y = []__init__它就会按预期工作。

于 2012-05-03T18:53:05.533 回答
2

这里发生的情况是,您实际上已将 x 重新定义为实例级别属性,并且您的类定义将它们都作为级别属性。

如果你这样做,你可以看到你原来的 x 仍然是 0。

>>> Object.x
0

由于您没有创建新列表,因此它采用了 class 属性。如果你要这样做:

>>> a.y = []
>>> b.y = []
>>> a.y.append(1)
>>> b.y.append(2)
>>> print a.y, b.y
[1] [2]

这就是你所期待的。真的,虽然你应该像这样定义你的类:

class Object(object):
    def __init__(self):
        self.y = []
        self.x = 0

(并且不要使用 Object 作为类名!)

于 2012-05-03T18:58:23.283 回答
1

设置实例属性而不是属性的最简单方法是使用__init__

当您引用实例属性(如a.y)时,解析器会首先尝试返回该属性,但如果未找到,则返回属性 ( Object.y)。

在您的情况下,仅定义了一个由所有实例共享的类属性。

于 2012-05-03T19:01:18.807 回答
1

唯一的方法是创建__init__方法

class Object:
  def __init__(self):
    self.x = 0
    self.y = []

这样一来,在 Object 的构造中,一个新的值将被赋予,并为.创建x一个新的 List 。y

您之前所做的方式为 Object 创建了两个类/静态变量,但仅y保持不变,因为它仅静态保存对真实 List 的引用,反映到 Object 的所有实例。

关于另一个问题的类/静态变量的更多信息: Python 中的静态类变量

*对不起,如果我使用了错误的术语,我更像是一个 Java 人 ;-)

于 2012-05-03T19:07:54.837 回答