3

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

I have this code

class Test(object):
  def __init__(self, var1=[]):
    self._var1 = var1

t1 = Test()
t2 = Test()

t1._var1.append([1])

print t2._var1

and I get "[[1]]" as the result. So clearly t1._var1 and t2._var1 are addressing the same list. If I put

t3 = Test()
print t3._var1

then I get "[[1]]" as well. So var1=[] seems to permanently bind var1 to the some list. I tried copying the list,

def __init__(self, var1=copy([])):

but got the same result, so the expression for the named argument appears to be evaluated prior to init being called, and it just gave var1 a copy of the empty list which was then shared amongst the instances.

So how do I use [] as a default value for a named argument?

Community
  • 1
  • 1
savagent
  • 2,114
  • 1
  • 13
  • 10
  • They do seem like duplicates. Sorry, I did look before I posted but I didn't see the other question. Having said that, none of the answers given for the other question show how to actually use a mutable default argument correctly. – savagent Nov 21 '12 at 00:08

1 Answers1

7

You can't use [] directly if you want each object to have an empty list. I tend to use a work around:

def __init__(self, var1=None):
    if var1 is None:
        var1 = []
    ....

Naturally this won't work if var1 can be None, you would need to use a different object.

Tim
  • 11,710
  • 4
  • 42
  • 43
  • This is the un-officially official recommended pattern for handling mutable default arguments. ([Example](http://effbot.org/zone/default-values.htm#what-to-do-instead)) – jathanism Nov 20 '12 at 23:44
  • Is this a deliberate design decision? What is the rationale? Why not just evaluate the expression when the function is called? – savagent Nov 20 '12 at 23:59
  • This isn't just "unofficially official", it's in the FAQ. And the rationale is there too. See http://docs.python.org/2/faq/design.html#why-are-default-values-shared-between-objects for details. – abarnert Nov 21 '12 at 00:04
  • If `None` is a value you want to support, you can create your own sentinel value, such as an object instance. E.g. `_sentinel = object(); class foo: def __init__(self, foo=_sentinel): if foo is _sentinel: foo = []; ...` – Blckknght Nov 21 '12 at 00:08
  • savagent@ Answer to "Why not just evaluate the expression when the function is called?" Because the expression for default value is evaluated only once at the time of creating the function object, not at the time of calling. – hynekcer Nov 21 '12 at 00:18
  • @hynekcer Yes, but my question was why is that the case. I found the answer though on the [question](http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument) linked to be Steven Rumbalski – savagent Nov 21 '12 at 00:27
  • 1
    savagent@ I wrote [a general answer to this closed and the related question](http://stackoverflow.com/a/13518071/448474). Particularly: Some `copy` of the original should be created in the body, not in the header of function, in order to prevent other unwanted side effects. A good programming technique is not to allow modifying the used actual input parameter or to do it only intentionally and very explicitely. That means it is confusing to specify a default value for a parameter that can be eventually also an output. Current implementation is not a problem IMO. – hynekcer Nov 22 '12 at 21:47