Конструктор Python делает странные вещи с необязательными параметрами [duplicate]

Возможный дубликат:
Наименьшее удивление в Python: изменяемый аргумент по умолчанию

Я хочу понять поведение и последствия питона__init__ конструктор. Кажется, что когда есть необязательный параметр и вы пытаетесь установить существующий объект на новый объект, необязательное значение существующего объекта сохраняется и копируется.

Посмотрите на пример:

В приведенном ниже коде я пытаюсь создать древовидную структуру с узлами и, возможно, многими дочерними элементами. В первом классеNodeBadконструктор имеет два параметра: значение и любые возможные дочерние элементы. Второй классNodeGood принимает только значение узла в качестве параметра. У обоих естьaddchild метод для добавления дочернего узла.

При создании дерева сNodeGood класс, работает как положено. Тем не менее, когда делаете то же самое сNodeBad класс, кажется, что ребенок может быть добавлен только один раз!

Приведенный ниже код приведет к следующему выводу:

Good Tree
1
2
3
[< 3 >]
Bad Tree
1
2
2
[< 2 >, < 3 >]

Что произошло?

Вот пример:

#!/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

Ответы на вопрос(2)

Ваш ответ на вопрос