1

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

I am not sure what this is called, and thus have had difficulties finding documentation for what is going on. I was hoping someone here might be able to point me in the right direction.

In the following example, where I have a list as a default value for a keyword argument, it behaves in a way I was not expecting:

class A(object):
    def __init___(self, c=[0,0]):
        self.c = c

class B(A):
    def __init__(self):
        super(B, self).__init__()

a = A()
b = B()

print a.c, b.c  # outputs [0, 0] [0, 0]

a.c[1] = 5

print a.c, b.c  # outputs [0, 5] [0, 5]

I understand that lists are mutable, but I had assumed that in the case of using a list as a default keyword argument, a 'new' list would be created each time. Is there documentation explaining why this is not the case?

Community
  • 1
  • 1
BrT
  • 619
  • 1
  • 5
  • 15
  • 2
    related: [“Least Astonishment” in Python: The Mutable Default Argument](http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument) – Paolo Moretti Oct 12 '12 at 08:52
  • This should be closed as an exact duplicates. It is also one of the most common problems. See @PaoloMoretti 's comment for better answers on this topic. This article probably explains it even better: http://effbot.org/zone/default-values.htm – K Z Oct 12 '12 at 08:54
  • http://docs.python.org/tutorial/classes.html#a-word-about-names-and-objects – avasal Oct 12 '12 at 08:55
  • @PaoloMoretti -- perfect, that is exactly what I was after, thanks. – BrT Oct 12 '12 at 08:59
  • @KayZhu -- I agree this is a dup of Paolo's link -- how do I close? – BrT Oct 12 '12 at 09:00
  • @BrT You don't really need to do anything, we just need one more vote to close it from a user who can either vote or close :) – K Z Oct 12 '12 at 09:02

1 Answers1

1

Python creates a list that you specified as the default value once time, and then assigns it by reference. So:

>>> a1, a2 = A(), A()
>>> a1.c is a2.c
True
>>> a1.c.append(42)
>>> a2.c
[42]

Using this:

class A(object):
    def __init___(self, c=None):
        self.c = c if c is not None else [0, 0]

For more information read this, and also you can see this popular question.

Community
  • 1
  • 1
defuz
  • 26,721
  • 10
  • 38
  • 60
  • Yes, this is how I fixed it, but I am interested in finding out the reason. – BrT Oct 12 '12 at 08:51
  • @BrT yes me too. All the explanations say "because it's mutable" but don't explain why mutability should lead to the sharing of the value in subsequent calls. – Bob Nov 02 '15 at 18:45