1

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

I just want to check that the way I'm expecting this to work is correct or not. Here is a simplified version of a class I'm writing:

class Foo(object):
     def __init__(self):
         pass
     def bar(self, test1=[], test2=[]):
         if test2:
             test1.append(1)
         print test1

Now, to me, test1 and test2 - unless set - should always be set as empty lists when the function bar is called. This means that when test1 is printed, there should only ever be one item in the list (provided you only give one item as an argument). However, this is not the case:

>>> i = Foo()
>>> i.bar()
[]
>>> i.bar(test2=[1])
[1]
>>> i.bar()
[1, 1]
>>> i.bar(test2=[1])
[1, 1, 1]

In this case, you'd expect a similar result using integers:

class Foo(object):
     def __init__(self):
         pass
     def bar(self, test1=0, test2=0):
         if test2:
             test1 += 1
         print test1

But here, test1 is always set to 0:

>>> i = Foo()
>>> i.bar()
0
>>> i.bar(test2=1)
1
>>> i.bar(test2=1)
1
>>> i.bar(test2=1)
1

It seems that the list is persistent in the function or class's namespace, but the integer is not.

This may be a misunderstanding on my part, so would just like some clarification.

Community
  • 1
  • 1
joedborg
  • 17,651
  • 32
  • 84
  • 118

1 Answers1

1

The default arguments of a function are set when the function is declared, not every time you call the function. Therefore the list that is made when the function is declared is only made once, and is referenced every other time you called the function. See also this question.

Because lists are mutable, when you change them, anything that references it changes as well. However integers are immutable (they can't be changed), so when you reassign a variable to another integer, only that variable changes, because it is referencing a different object.

Community
  • 1
  • 1
Volatility
  • 31,232
  • 10
  • 80
  • 89