2012-05-03 38 views
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引用相同的列表。我怎样才能让他们分开?优选地,不需要增加方法。

+0

打印斧头,B,Y的应该打印这个:1 [] –

+1

这是'__init__'的用途。你为什么不想用它? –

+0

@gnibbler如果我确切知道Python对象如何工作我不会在这里:) – devtk

回答

2

这里发生的事情是,你实际上已经实际上重新定义X为实例级别属性,和你的类定义了它们既是级别的属性。

如果你这样做,你可以看到你的原始x仍处于0

>>> Object.x 
0 

只要你不创建一个新的列表,它走的是类属性。如果你这样做:

>>> 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 

(不要使用对象的类名!)

+0

美丽的解释,谢谢!别担心,我的真实物体不是'物体':) – devtk

3

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

1

的最简单的方法来设置例如属性,而不是类的属性中使用__init__

当你引用一个实例属性(如a.y)解析器试图返回第一,但如果没有找到它的属性(Object.y)被返回。

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

1

做到这一点的唯一方法是在对象的构造创建__init__方法

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

这样一来,新的值将被assined到x和一个新的列表将y创建

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

更多关于类/关于这个问题的其他静态变量: Static class variables in Python

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

相关问题