Конструктор 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