Python constructor does weird things with optional parameters
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
least astonishment in python: the mutable default argument
我想了解python
看一个例子:
在下面的代码中,我试图用节点和可能多个子节点来构建树结构。在第一类
用
下面的代码将产生以下输出:
1 2 3 4 5 6 7 8 9 10 | Good Tree 1 2 3 [< 3 >] Bad Tree 1 2 2 [< 2 >, < 3 >] |
阙葩萨?
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #!/usr/bin/python class NodeBad: def __init__(self, value, c=[]): self.value = value self.children = c def addchild(self, node): self.children.append(node) def __str__(self): return '< %s >' % self.value def __repr__(self): return '< %s >' % self.value class NodeGood: def __init__(self, value): self.value = value self.children = [] def addchild(self, node): self.children.append(node) def __str__(self): return '< %s >' % self.value def __repr__(self): return '< %s >' % self.value if __name__ == '__main__': print 'Good Tree' ng = NodeGood(1) # Root Node rootgood = ng ng.addchild(NodeGood(2)) # 1nd Child ng = ng.children[0] ng.addchild(NodeGood(3)) # 2nd Child print rootgood.value print rootgood.children[0].value print rootgood.children[0].children[0].value print rootgood.children[0].children print 'Bad Tree' nb = NodeBad(1) # Root Node rootbad = nb nb.addchild(NodeBad(2)) # 1st Child nb = nb.children[0] nb.addchild(NodeBad(3)) # 2nd Child print rootbad.value print rootbad.children[0].value print rootbad.children[0].children[0].value print rootbad.children[0].children |
问题是,可选参数的默认值只是一个实例。例如,如果您说
所以基本上,您应该只对可选参数的默认值使用不可变的日期类型,如
1 | def __init__(self, value, c=None): |
然后您可以在方法体中创建一个新的列表:
1 2 | if c == None: c = [] |
可变的默认参数是混淆的根源。
看到这个答案:"最小的惊讶"和可变的默认参数