2016-02-03 81 views
0

此代碼旨在創建圖形實現。但是,所有節點「self.children」鏈接到內存中的相同列表,因此將子節點添加到其中任何節點都會將其添加到所有節點中。我無法想象爲什麼會發生這種情況,我已經多次上過這樣的課,而且沒有這樣的問題。Python初始化默認值創建類的鏈接實例

我的意思是,僅僅因爲你在默認值中定義了一個列表並不意味着我在那裏做了一個列表,是嗎?這是混亂...

class DescisionNode(object): 
    def __init__(self,data,score,childs=[]): 
     self.data = data 
     self.score = score 
     self.parent = None 
     self.children = childs 
    def getTop(self): 
     if self.parent == None: 
      return self 
     else: 
      return self.parent.getTop() 
    def getEnds(self): 
     out = [] 
     if len(self.children)==0: 
      return [self] 
     else: 
      print(self,self.children) 
      for n in self.children: 
       out += n.getEnds() 
      return out 
    def add(self, newNode): 
     if newNode.parent == None: 
      newNode.parent = self 
     else: 
      raise Exception("Parent already exists.") 
     if newNode is self: 
      raise Exception("self may not be child") 
     self.children.append(newNode) 
+0

考慮構建向前列表(下一個節點)比向後更容易(父節點) –

回答

-1

這是由於這樣的:http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments

Python的默認參數進行評估,一旦被定義的功能時,不會在每次調用函數時(比如它是在比如Ruby)。這意味着如果您使用可變默認參數並對其進行變異,那麼您將會爲該函數的所有將來調用改變該對象。

你可以找到一些討論在這裏: "Least Astonishment" and the Mutable Default Argument

它從一個事實,即在Python函數是第一類對象,而不僅是一段代碼來簡單。一旦你開始這樣思考,那麼它就完全有意義了:函數是一個正在被定義的對象;默認參數是一種「成員數據」,因此它們的狀態可能會從一個調用改變到另一個 - 與其他任何對象完全相同

+0

雖然此鏈接可能回答問題,但最好在此處包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/11124740) –

+0

編輯與節選。謝謝。 –