阻止引用相同列表的成员对象

时间:2012-05-03 18:50:09

标签: python list object

这应该很简单......

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 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

如果这样做,您可以看到原始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作为类名!)

答案 2 :(得分:1)

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

当您引用实例属性(如a.y)时,解析器会先尝试返回该属性,但如果找不到属性({ {1}})被退回。

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

答案 3 :(得分:1)

唯一的方法是创建__init__方法

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

这样,在构建对象时,新值将被x限制,而y将为创建

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

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

*对不起,如果我使用错误的条款,我更像是一个Java人员; - )