3

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

I have the following code:

class Node(object):
    def __init__(self, value = 0, children = {}):
        self.val = value
        self.children = children

    def setChildValue(self, index, childValue):
        self.children[index] = Node(childValue)

n = Node()
n.setChildValue(0,10)
print n.children
n2 = Node()
print n2.children

And it prints:

{0: <__main__.Node object at 0x10586de90>}
{0: <__main__.Node object at 0x10586de90>}

So my question is, why is children defined in n2? Children is an instance variable and yet it's acting like a class variable.

Thanks

Community
  • 1
  • 1
Alex Varga
  • 1,752
  • 2
  • 14
  • 17

3 Answers3

4

You're assigning the same dictionary to children on every instance.

kindall
  • 178,883
  • 35
  • 278
  • 309
2

When you define the function __init__ you give it a dictionary as a default argument. That dictionary is created once (when you define the function) and then used every time __init__ is called.

More information: http://effbot.org/zone/default-values.htm

Matt
  • 3,651
  • 3
  • 16
  • 35
1

As indicated in Martijn's comment and kindall's answer, you are running into the mutable default argument behavior which bites most Python developers at some point, here is how you can modify Node.__init__() so that it works the way you expect:

class Node(object):
    def __init__(self, value = 0, children = None):
        self.val = value
        if children is None:
            self.children = {}
        else:
            self.children = children
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306