2011-10-23 57 views
3

在Python中,我實例化一個類兩次並將它們存儲到2個不同的變量中。爲什麼第二個對象包含第一個對象的副本?我知道這是一個副本,因爲我更改了一個對象中的值,但它不會改變其他值。例如:實例化類保留引用

我有以下類:

class HistoricalData: 
    dataPoints = {} 

然後我和值類實例化和填充數據點:

hd1 = HistoricalData() 
hd1.dataPoints["channel1"] = 1 
hd1.dataPoints["channel2"] = 2 
hd1.dataPoints["channel3"] = 3 

我還是那句話實例化類,並再次用值填充它:

hd2 = HistoricalData() 
hd2.dataPoints["channel1"] = 10 

當我打印hd1.dataPoints和hd2.dataPoints的值時,我g等如下:

{'channel1': 1, 'channel2': 2, 'channel3': 3} 
{'channel1': 10, 'channel2': 2, 'channel3': 3} 

本字典有在所述第二物體的第一副本,因爲在通道1中的值與第二被改變而不是第一。

我以爲當你實例化一個類時,所有的值將被默認爲類中定義的值。我錯過了什麼嗎?

+1

你在什麼地方弄錯了。 Johhnyweb的回答是正確的,儘管如此,但如果運行上面的代碼,您肯定會看到兩個實例的'dataPoints'中的值都變爲'10'。只有一本字典。 「我知道這是一個副本,因爲我改變了一個對象的值,並且不會改變其他值。」 - 呃,事實並非如此。 – agf

回答

10

您已聲明class variable而不是instance variable

類變量在之間共享class。這意味着當你更新一個HistoricalDataobject時,你全部更新它們。

實例變量是本地的每個實例的一個class。這些通常在__init__()特殊方法中初始化,當創建每個實例時調用這個方法。

因此你應該初始化datapoints像這樣來得到你想要的結果:

class HistoricalData(object): 

    def __init__(self): 
     self.dataPoints = {} 
+0

如果我添加了一個像字符串這樣的簡單類型的新實例變量,這還需要在__init__中定義嗎? –

+0

@DannyTsang:這不是簡單的類型。 'self.name ='''同樣需要在'__init __()'(或類似的)中初始化*成爲*實例變量*。 – Johnsyweb

+0

謝謝@Johnsyweb –