Search code examples
pythoninheritanceparent-childsuperbase-class

Why super() is calling constructor of class Parent1 only and not calling constructor of class Parent2?


class Parent1:
    def __init__(self):
        self.data1 = 10
        print("parent1")

class Parent2:
    def __init__(self):
        self.data2 = 20 
        print("parent2")

class child(Parent2,Parent1):
    def __init__(self):
        print("this is child class")
        super().__init__()
        print(self.data1)
        print(self.data2)
        
obj = child()

Output:

this is child class
parent2
Traceback (most recent call last):
  File "f:/Project2020/Rough Work/rough2.py", line 18, in <module>
    obj = child()
  File "f:/Project2020/Rough Work/rough2.py", line 15, in __init__
    print(self.data1)
AttributeError: 'child' object has no attribute 'data1'

Solution

  • Answer to your question: in python there is an inheritance chain. In your case this inheritance chain looks like [Child, Parent2, Parent1],
    so kinda for the python compiler there's no such thing as multiple inheritance. super() is just a short-hand to walk one step up the inheritance chain. Therefore your statement is equal to Parent2.__init__() and indeed super().__init__() calls Parent2.__init__() as it should.
    So you also need to call Parent1.__init__() from class Child.

    I suggest writing:

    class Parent1:
        def __init__(self):
            self.data1 = 10
            print("parent1")
    
    class Parent2:
        def __init__(self):
            self.data2 = 20 
            print("parent2")
    
    class Child(Parent2,Parent1):
        def __init__(self):
            print("this is child class")
            Parent2.__init__(self)
            Parent1.__init__(self)
            print(self.data1)
            print(self.data2)
    

    In this situation the code is clearer if you don't use super(). This code may look odd but here using super() would be just confusing anyway.