2010-11-15 104 views
1

當爲我創建的類調用一個對象的新實例時,我的一個類的實例剛剛被覆蓋。爲什麼會這樣呢?示例如下。Python類 - 實例被覆蓋?

我的類定義如下:

class my_class: 
    attribute = "" 
    examples = [] 
    children = [] 
    d = {} 
    def __init__(self, attribute, e): 
     self.attribute = attribute 
     self.examples = e 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

我想提出一個初始實例爲這樣:

root = my_class(some_attribute, data) 

然後,我創建另一個實例是這樣的:

child = my_class(different_attribute, root.examples[somewhere_1:somewhere_2]) 

最後,我最初的'根'現在與'孩子'有些相同,'根'應該沒有改變。爲什麼是這樣!?

回答

4

我不認爲你用的attributeexampleschildrend你認爲你正在做的初始化做。那些現在是類的屬性,而不是每個實例的屬性。如果您希望類有attributeexampleschildrend其自身的屬性的每個實例,則應該寫:

class my_class: 
    def __init__(self, attribute, e): 

     self.attribute = attribute 
     self.examples = e 
     self.children = [] 
     self.d = {} 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 
+0

啊!你是對的。非常感謝你清除那個 – 2010-11-15 00:19:55

1

當你定義在類定義的變量,它們是類屬性。

>>> my_class.examples is my_class().examples 
True 

is檢查它們是完全相同的對象,而不是隻是相等。例如,True == 1,但True is not 1。)

作爲list S和dict s爲可變的,這意味着變化my_class.examplesroot.exampleschild.examples將反映在所有其他。

你應該做這樣的事情的方式是,設置它的構造函數中:

class my_class: 
    def __init__(self, attribute, e): 
     self.attribute = attribute 
     self.examples = e 
     self.children = [] 
     self.d = {} 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

你可能還希望與self.examples = e[:]這將使列表的淺副本替換self.examples = e。否則:

>>> data 
[1, 2, 3, 4, 5] 
>>> root = my_class(some_attribute, data) 
>>> root.examples 
[1, 2, 3, 4, 5] 
>>> data += [6, 7] 
>>> root.examples 
[1, 2, 3, 4, 5, 6, 7] 
>>> # ... because: 
>>> root.examples is data 
True 

旁註:推薦的Python風格將您的類作爲MyClass。我建議你閱讀PEP 8.