2012-06-25 24 views
1

代碼:在python中,將子項添加到root.children(list)和child.children(list)已更改?

class Node: 
    def __init__(self, key, children=[]): 
     self.key = key 
     self.children = children 

    def __repr__(self): 
     return self.key 

執行:

root = Node("root") 
child = Node("child") 
root.children.append(child) 
print child.children 
print root.children[0].children 

結果:

[child] 
[child] 

這是很奇怪的,爲什麼呢?

Python的版本是2.7.2。

+6

作爲默認值的可變對象! 'def __init __(self,key,children = None):\\ children = children或[]' – astynax

+0

這是python的一個bug? – LeoDT

+1

不,看到這個問題:http://stackoverflow.com/q/1132941/623518 – Chris

回答

5

你不應該使用可變對象作爲參數的默認值(除非你完全知道你在做什麼)。有關說明,請參閱this article

而是使用:

class Node: 
    def __init__(self, key, children=None): 
     self.key = key 
     self.children = children if children is not None or [] 
+0

或者:'self.children = children如果孩子不是None else []'或者'self.children = []如果children是None else children'。 – glglgl

+0

明白了,謝謝。 – LeoDT

+1

'孩子或[]'與'如果孩子不是無'並不完全一樣,因爲有許多錯誤值不是'無'。這可能對你很重要,也可能不重要,但通常的習語是後者。 – katrielalex

0
class Node: 
    def __init__(self, key,children): # don't use children =[] here, it has some side effects, see the example below 
     self.key = key 
     self.children =children 

    def __repr__(self): 
     return self.key 

root = Node("root",[]) 
child = Node("child",[]) 
root.children.append(child) 
print root.children 
print root.children[0].key 

輸出:

[child] 
child 

例如:

def example(lis=[]): 
    lis.append(1) #lis persists value 
    print(lis) 
example() 
example() 
example() 

輸出:

[1] 
[1, 1] 
[1, 1, 1] 
+2

爲什麼顯式傳遞一個空列表是一個很好的解決方案? –

+0

@Secator不,它不是,但是當我寫這個時,我的腦海中並沒有出現「孩子或者」事情。 –

相關問題