tags:

views:

124

answers:

3

I am noticing the following:

class c:
  def __init__(self, data=[]):
    self._data=data
a=c()
b=c()
a._data.append(1)
print b._data
[1]

Is this the correct behavior?

+7  A: 

Yes, it's correct behavior.

However, from your question, it appears that it's not what you expected.

If you want it to match your expectations, be aware of the following:

Rule 1. Do not use mutable objects as default values.

def anyFunction( arg=[] ):

Will not create a fresh list object. The default list object for arg will be shared all over the place.

Similarly

def anyFunction( arg={} ):

will not create a fresh dict object. This default dict will be shared.

class MyClass( object ):
    def __init__( self, arg= None ):
        self.myList= [] if arg is None else arg 

That's a common way to provide a default argument value that is a fresh, empty list object.

S.Lott
`Will never work.` is a bit harsh. `Won't give you a new empty mutable object on each call`, seems a little more balanced. If you know this happens you might actually want to use this behaviour.
MattH
@MattH: Reusing the same mutable object via a default value is so odd that it defies finding a sensible use case. It's a *default* value, so it may (or may not) get used as such depending on the client's use of the interface. It would be so hard to diagnose problems with this that I stand by my original formulation. Especially for n00bz.
S.Lott
You should add an example of how to work around this. Otherwise the answer is good and correct.
ironfroggy
There's a sensible use case for almost everything. For mutable default values I'd choose a simple memoization strategy, for example as described by Alex Martelli here: http://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time-in-python/1651284#1651284
Scott Griffiths
@Scott Griffiths: While there's a use case, I would debate "sensible". Yes, it works, but so does unreadable spaghetti code. Using mutable objects as *default* values is a bad idea. In the example question, the default value syntax is used to provide a hidden memoization context; it doesn't fit the usual design patterns for "default" because there is o sensible reason to provide a real value.
S.Lott
+4  A: 

This is a classic pitfall. See http://zephyrfalcon.org/labs/python_pitfalls.html, section 5: "Mutable default arguments"

unutbu
+1  A: 

Always make functions like this then:

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

    self._data = data

Alternatively you could also use data = data or [], but that prevents the user from passing empty parameters ('', 0, False etc.).

poke
Of course you can also do `if not data: data = []`.
voyager
your example `data = data or []` works just fine for empty lists being passed. You'd be saying `data` will be `[] or []` so it will look at the first one and see that it evaluates to "false", then it will take the other value.
tgray
I know, my point was that when you pass `False` for example, `[]` will be used as the value, although you passed `False`.
poke