Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: derived classes access dictionary of base class in the same memory location

I'm wondering why a dictionary, that is defined in a base class and is accessed from derived classes, is obviously present only in one memory location. A short example:

class BaseClass:
    _testdict = dict()
    _testint = 0

    def add_dict_entry(self):
        self._testdict["first"] = 1

    def increment(self):
        self._testint += 1

class Class1(BaseClass):
    pass

class Class2(BaseClass):
    pass

object1 = Class1()
object2 = Class2()

object1.add_dict_entry()
object1.increment()
print(object2._testdict)
print(object2._testint)

and the output is:

{'first': 1}
0

Why does a call to the "add_dict_entry" of object1 affect the dictionary of object2? Using integers ("increment") the base class variable is not affected.

Thanks a lot.

Lorenz

like image 990
Lorenz Winkler Avatar asked Aug 24 '12 14:08

Lorenz Winkler


People also ask

What is the connection between the base class and the derived class?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive.

Are class methods inherited Python?

Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.

How do I call an inheritance in Python?

Two built-in functions isinstance() and issubclass() are used to check inheritances. The function isinstance() returns True if the object is an instance of the class or other classes derived from it. Each and every class in Python inherits from the base class object .

What is base class derive class?

1. A base class is an existing class from which the other classes are derived and inherit the methods and properties. A derived class is a class that is constructed from a base class or an existing class. 2. Base class can't acquire the methods and properties of the derived class.


2 Answers

It's because _testdict is a class variable: it's defined only once, when the class is initially constructed. If you want it to be separate for each instance, make it an instance variable:

class BaseClass:
    _testint = 0

    def __init__(self):
        self._testdict = dict()

    def add_dict_entry(self):
        self._testdict["first"] = 1

(Note that you'd need to create __init__ methods for Class1 and Class2 as well, both of which would have to call BaseClass.__init__(self)).

_testint behaves differently because you're performing a rebinding operation on it rather than a mutating operation. ints are immutable, so you can't "change" one- self._testint += 1 is just syntactic sugar for self._testint = self._testint + 1. Similarly, you can perform a rebinding operation on self._testdict that won't be shared between instances- for example, self._testdict = {} will reset only that instance's _testdict.

like image 98
David Robinson Avatar answered Nov 09 '22 22:11

David Robinson


In python, int is immutable, therefore the += operation will rebound the class variable into an instance variables. On the other hand, a dictionary indexing mutates the dictionary in place. A more comparable example would be

def add_dict_entry(self):
    # create a new dict
    tmp = dict(self._testdict)
    tmp["first"] = 1

    # shadow the class variable with an instance variables
    self._testdict = tmp
like image 41
Lie Ryan Avatar answered Nov 09 '22 20:11

Lie Ryan