Duplicar posible:
least astonishment in python: the mutable default argumentPython constructor hace cosas raras con los parámetros opcionales
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 para un nuevo objeto, el valor opcional del objeto existente se conserva y se copia.
vistazo a un ejemplo:
En el siguiente código que estoy tratando de hacer una estructura de árbol con nodos y posiblemente muchos niños. En la primera clase NodeBad
, el constructor tiene dos parámetros, el valor y los posibles elementos secundarios. La segunda clase NodeGood
solo toma el valor del nodo como parámetro. Ambos tienen un método addchild
para agregar un elemento secundario a un nodo.
Al crear un árbol con la clase NodeGood
, funciona como se esperaba. Sin embargo, al hacer lo mismo con la clase NodeBad
, parece como si un niño solo pudiera agregarse una vez.
El código de abajo resultará en la siguiente salida:
Good Tree
1
2
3
[<3>]
Bad Tree
1
2
2
[<2>, <3>]
Que Pasa?
Aquí es 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
duplicado de http://stackoverflow.com/questions/1132941/least-astonishment-in-python -the-mutable-default-argument – sth