El constructor de Python hace cosas raras con parámetros opcionales [duplicado]
Posible duplicado:
menos asombro en python: el argumento predeterminado mutable
Quiero entender el comportamiento y las implicaciones de la pitón.__init__
constructor. Parece que cuando hay un parámetro opcional e intenta establecer un objeto existente en un nuevo objeto, el valor opcional del objeto existente se conserva y copia.
Mira un ejemplo:
En el siguiente código, estoy tratando de hacer una estructura de árbol con nodos y posiblemente muchos hijos. En la primera claseNodeBad
, el constructor tiene dos parámetros, el valor y cualquier posible hijo. La segunda claseNodeGood
solo toma el valor del nodo como parámetro. Ambos tienen unaddchild
Método para agregar un hijo a un nodo.
Al crear un árbol con elNodeGood
clase, funciona como se esperaba. Sin embargo, al hacer lo mismo con elNodeBad
clase, ¡parece que un niño solo se puede agregar una vez!
El siguiente código dará como resultado la siguiente salida:
Good Tree
1
2
3
[< 3 >]
Bad Tree
1
2
2
[< 2 >, < 3 >]
Que pasa
Aquí está el ejemplo:
#!/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