2012-05-03 37 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的人;-)

相關問題