2012-11-02 133 views
0

好,所以,我真的不知道如何在一個簡潔的短語字這個問題,因此如果國防部能想出一個更好的標題,請修復它。Python字典重寫錯誤?

因此,可以說你有一個模塊 「testModule.py」

# testModule.py  
data = {'x': 1, 'y': 2, 'z': 3} 

class A: 
    def __init__(self): 
     pass 

class B(A): 
    def __init__(self): 
     self.classData = data 

class C(B): 
    def __init__(self): 
     B.__init__(self) 
     self.classData = {'x': 2, 'y': 2, 'z': 3} 

,並導入testModule在文件 「test.py」

# test.py 
import testModule 

b = testModule.B() 
c = testModule.C() 

print test.data 
print b.classData 
print c.classData 

當您運行test.py你:

{'x': 1, 'y': 2, 'z': 3} 
{'x': 1, 'y': 2, 'z': 3} 
{'x': 2, 'y': 2, 'z': 3} 

這是預期的,精細化,花花公子......

但如果你是在testModule改變C級到:

class C(B): 
    def __init__(self): 
     B.__init__(self) 
     self.classData['x'] = 2 

然後運行test.py你:

{'x': 2, 'y': 2, 'z': 3} 
{'x': 2, 'y': 2, 'z': 3} 
{'x': 2, 'y': 2, 'z': 3} 

所以我想我的問題是:爲什麼當你改變通過參照在字典中單個元件它改變元件,用於所有後續類的字典屬於基本模塊字典(我希望有意義)。當你重新定義字典時,它不會這樣做。請幫忙,因爲這個問題真的開始困擾我。

也許我很高興知道,這些.py文件是結構化他們,因爲我目前一個項目遇到此問題的方式,我的類都遵循相同的結構。 感謝所有在先進, Jeraldamo

+1

原因是python對象引用技術。 http://stackoverflow.com/questions/12797749/python-and-reference-passing-limitation/12797976#12797976 –

+0

在您的例子情況下,你使用的對象從用C父類,在C –

回答

3

其實你引用在所有類別中一個全局的和可變的對象。所以你會看到所有這些變化的反映。這是因爲你正在改變同一個對象。您將需要copy()字典爲每個類的實例,以獲得全球性的唯一副本。

self.classData = data.copy() 

然而,即使這樣可能會導致你的問題,如果字典的值也是可變的。這是因爲copy()方法只做淺拷貝。最保險的方法就是做一個深拷貝,使用copy模塊的deepcopy的功能。把它放在你的類初始化器中。

self.classData = copy.deepcopy(data) 
+0

沒有確定下來,還有我想你意思是「針對每個實例」而不是「針對每個類」。 – eryksun

+0

@eryksun是,已編輯。謝謝。 – Keith