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

Respuestas a la pregunta(2)

Su respuesta a la pregunta