Python构造函数使用可选参数来做奇怪的事情
可能重复:
最不惊讶的是python:可变的默认参数
我想了解python __init__
构造函数的行为和含义。 看起来像有一个可选参数,并且您尝试将现有对象设置为新对象时,现有对象的可选值将被保留并复制。
看一个例子:
在下面的代码中,我试图制作一个带有节点和可能有很多孩子的树结构。 在第一类NodeBad
,构造函数有两个参数,值和任何可能的子NodeBad
。 第二类NodeGood
只将该节点的值作为参数。 两者都有一个addchild
方法来为节点添加一个子节点。
使用NodeGood
类创建树时,它按预期工作。 但是,在NodeBad
类中做同样的事情时,似乎只能添加一次子!
以下代码将导致以下输出:
Good Tree
1
2
3
[< 3 >]
Bad Tree
1
2
2
[< 2 >, < 3 >]
Que Pasa?
这是例子:
#!/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
问题是,可选参数的默认值只有一个实例。 例如,如果你说def __init__(self, value, c=[]):
那么每次调用代码使用一个可选参数时,同样的list []
将被传递给方法。
所以基本上你只能使用不可变的日期类型,例如None
作为可选参数的默认值。 例如:
def __init__(self, value, c=None):
然后你可以在方法体中创建一个新的列表:
if c == None:
c = []
可变的默认参数是混淆的来源。
看到这个答案:“最小的惊讶”和可变的默认参数
链接地址: http://www.djcxy.com/p/28527.html上一篇: Python constructor does weird things with optional parameters