0

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

I am confused with the following. I have a base class:

class MyBase:

    def __init__(self, store=set()):
        self._store = store

Now child classes inherit MyBase

class Child1(MyBase):
    pass

class Child2(MyBase)
    pass

Then,

child1 = Child1()
child2 = Child2()

print(id(child1._store) = id(child2._store))
>>> True

Why do these instances have a shared _store??

I would really appreciate if you could help me out.

Regards, Nav

Community
  • 1
  • 1
Nav
  • 741
  • 1
  • 6
  • 12
  • Obviously, this is because childes inherits attribute _store from they parent. – Denis Sep 06 '12 at 06:39
  • 3
    @Denis: No, they don't inherit `_store`. It is because the `__init__` method's default argument is evaluted only once, when the method is defined, and that same default argument is used to initialize the `_store` variable for each instance of all the classes. – BrenBarn Sep 06 '12 at 06:47
  • @BrenBarn And so on ? All childs inherits attribute from base class. It works like this and I dont understand what confuses you. – Denis Sep 06 '12 at 06:59
  • 3
    @Denis you obviously don't understand the issue. – atzz Sep 06 '12 at 07:08
  • Agree, @Denis is simply wrong. – Daniel Roseman Sep 06 '12 at 08:23

1 Answers1

3

The set() is created once at the time of parsing the __init__ of the parent class.

To fix it, change the code like this:

class MyBase:

    def __init__(self, store=None):
        if store is None:
            store = set()
        self._store = store
Thomas Vander Stichele
  • 36,043
  • 14
  • 56
  • 60
  • 1
    Correction: in the original code, the set is created at the time of **parsing** the `__init__` method, and becomes a part of the method definition. The explanation as you worded it doesn't make sense. – atzz Sep 06 '12 at 07:06
  • atzz, sure, adding the missing word – Thomas Vander Stichele Sep 06 '12 at 08:46
  • Yea, but why is the set() created once? Is there an explanation for this? I would assume that the instance of set() in both cases would be different? – Nav Aug 20 '13 at 22:04
  • Nav, in the initial example, it's only created once because the code is executed line by line, and the line that creates the class object for MyBase only parses the argument to default once. At that time, the set() is created, and used as the default for all instantiations. – Thomas Vander Stichele Aug 23 '13 at 19:10