“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.