0

I am confusing about the default arguments in Python. Here are my code:

#!/usr/bin/env python
import sys 
class Node(object):
     def __init__(self, ID=str(), items=[]):
         self.ID = ID
         self.items = items

 if __name__ == '__main__':
     a = Node('1')
     b = Node('2')
     b.items.append('sth.')
     c = Node('3')
     print a.items
     print b.items
     print c.items

The output is:
['sth.']
['sth.']
['sth.']

I just change the b instance. Why all instances are changed?

1 Answers1

4

This is a case of reference. Since the list items is mutable (can be directly changed with an internal method), any change you make to it in any function is reflected in all references to it.

For example, if you have the following code:

def f(x):
    x.append(5)

a = [1, 2, 3]
f(a)
# a is now [1, 2, 3, 4], even in the global scope

This occurs because a is a mutable list, and so it is passed by reference.

So when you use items = [], you are creating a blank list when the program is started, but not every time you create a new instance. Instead, each instance refers to the same list, created when the class was "declared". So, since each instance refers to the same list, they are all changed.

To fix this, change your constructor to:

def __init__(self, ID=str(), items=None): # you can also use '' instead of str()
    if not items: items = []
    # everything else

A few good links to explain this better/in a different way:

There are a ton of other questions like this out there, just search [python] None as default argument.

Community
  • 1
  • 1
Rushy Panchal
  • 16,979
  • 16
  • 61
  • 94
  • Python absolutely does not check if a parameter is mutable and then do pass by reference if it is. I wish people wouldn't repeat this in otherwise fine answers. – Wooble Aug 12 '13 at 14:38
  • @Wooble Not sure what you mean. I'm just saying that mutable objects are passed by reference. – Rushy Panchal Aug 12 '13 at 14:40
  • They aren't. Python doesn't do pass by reference. I suggest reading http://stackoverflow.com/a/986145/110707 – Wooble Aug 12 '13 at 14:40