__init__(self, list=[]) only makes one list rather than a new one for every instantiation?

Go To StackoverFlow.com

1

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

Why is this:

class Test:
    def __init__(self, items=[]):
        self.items=items

different than this:

class Test2:
    def __init__(self, items=None):
        if items:
           self.items=items
        else:
           self.items = []

Those seem like they should do the same thing, but:

>>>t = Test()
>>>t.items.append("stuff")
>>>t.items
['stuff']
>>>t2 = Test()
>>>t2.items
['stuff']

Ok, so with Test(), there's only one list being created, and everyone is accessing it, despite what I thought was explicitly setting items in the constructor and not putting it in the class namespace. But with Test2:

>>>t = Test2()
>>>t.items.append("stuff")
>>>t.items
['stuff']
>>>t2 = Test2()
>>>t2.items
[]

That's working the way I expect. Test also doesn't share data between instances if you call it explicitly with an empty list rather than let the default do the work, as in t = Test([]).

So is it that defaults are only created once at compile time, rather than dynamically? Is that only true for class definitions, not for functions in general, or is this a more general pitfall for using defaults in argument lists? (Answer: it happens for functions, too.)

Note that I tested this with a string instead of a list, and got expected behavior where data was not shared between instances. But it does happen with dicts as well.

2012-04-04 00:41
by Dave Orr


2