1

I cannot understand how this works. How come instance b of the Node as shown in code below knows about wordlist?

class Node():
def __init__(self,wordList=[]):
    self.wordList = wordList

a = Node()
b = Node()

a.wordList.append("hahaha!")
print b.wordList

hahaha!

Ardavan
  • 1,896
  • 1
  • 13
  • 8
  • Not sure this should be closed as duplicate of linked question. For sure the title should be changed to something more meaningful to be searchable for others – joaquin Feb 08 '14 at 07:01

3 Answers3

3

It is a common mistake in Python until you get the way it works, and them learn to avoid this intuitivelly.

The problem is that the default parameter to the __init__method wordlist, which is am empty list denoted by [ ] is created just once, when the class body is parsed.

After that, each invocation to the __init__ method (made automatically at object instantiation) passes the same object - the single empty list - as parameter to the function. Therefore, in the example above, all instances of Node will point to the same list- which is the problem you detected.

The correct pattern to avoid the problem is like this:

class Node(object):
def __init__(self,wordList=None):
    if wordlist is None: wordlist = [] 
    self.wordList = wordList

This way, a new empty ist is created at each __init__ invocation.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
2

In python default arguments are kept with the function, they are evaluated once when function definition is evaluated, as you have only one method used by all instances of that class, hence only one wordList default for that method and instances, so they act like a static variable in C, that is why you should never have mutable default arguments, read this for more details http://effbot.org/zone/default-values.htm

Anurag Uniyal
  • 85,954
  • 40
  • 175
  • 219
0

This might make it a bit clearer:

class Node():
    def __init__(self,wordList=[]):
        self.wordList = wordList

a = Node()
b = Node()

print(id(a.wordList))
print(id(b.wordList))

which results in something like

41474968
41474968

... in other words, a.wordList and b.wordList both refer to the same list.

Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99