Python constructor does weird things with optional parameters

Posted by christangrant on Stack Overflow See other posts from Stack Overflow or by christangrant
Published on 2010-05-24T19:24:57Z Indexed on 2010/05/24 19:31 UTC
Read the original article Hit count: 320

Can you help me understand of the behaviour and implications of the python __init__ constructor. It seems like when there is an optional parameter and you try and set an existing object to a new object the optional value of the existing object is preserved and copied. Ok that was confusing... so look at an example I concocted below.

In the code below I am trying to make a tree structure with nodes and possibly many children . In the first class NodeBad, the constructor has two parameters, the value and any possible children. The second class NodeGood only takes the value of the node as a parameter. Both have an addchild method to add a child to a node.

When creating a tree with the NodeGood class, it works as expected. However, when doing the same thing with the NodeBad class, it seems as though a child can only be added once!

The code below will result in the following output:

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

Que Pasa?

Here is the Example:

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

© Stack Overflow or respective owner

Related posts about python

Related posts about constructor