0

In python i have 3 classes a,b,c. class c is subclass of a,b. now when I'm creating object of class c, the constructor of only class c is beig called. I was expecting the constructor of class a,b also to be called.

class a:
    def __init__(self):
        print("initializing a")
class b:
    def __init__(self):
        print("initializing b")
class c(a,b):
    def __init__(self):
        print("initializing c")
e=c()

I got this result

initializing c

I was expecting

initializing a

initializing b

initializing c

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    If you want the other `__init__` to be called, you have to call them - it's not automatic. – wim Mar 27 '23 at 18:03
  • 1
    You were wrong to expect that, c's constructor essentially overwrites the super classes' constructors (just like how other methods would work). Don't bring assumptions from other languages to Python. – RemcoGerlich Mar 27 '23 at 18:06

3 Answers3

0

I think you search for Multiple Inheritance, so you have to use the super().__init__()[for python 3, only], like this example [which works for python 2 and 3]:

class A:
    def __init__(self):
        super(A, self).__init__()
        print("initializing A")
class B:
    def __init__(self):
        super(B, self).__init__()
        print("initializing B")

class C(B, A):
    def __init__(self):
        super(C, self).__init__()
        print("initializing C")
e=C()

Output:

initializing A
initializing B
initializing C

A good description about super() you will find here. By the way, PEP 8: Class names should normally use the CapWords or CamelCase convention.

Hermann12
  • 1,709
  • 2
  • 5
  • 14
0

In Python, when you define a subclass that inherits from multiple parent classes, the constructor of only the first parent class listed in the subclass definition is automatically called. This is because, in Python, the method resolution order (MRO) determines the order in which the constructors of the parent classes are called.

In your example, since a is listed before b in the definition of c, only the constructor of a is called, and the constructor of b is not called. To call the constructor of b, you can call it explicitly from the constructor of c using super() function like this:

class a:
    def __init__(self):
        print("initializing a")

class b:
    def __init__(self):
        print("initializing b")

class c(a, b):
    def __init__(self):
        super().__init__()  # Call the constructor of a
        b.__init__(self)    # Call the constructor of b
        print("initializing c")

e = c()

Here, super().init() calls the constructor of a, and b.init(self) calls the constructor of b. This will output the expected result:

initializing a
initializing b
initializing c
nidea1
  • 66
  • 5
-3

You have to call the constructors of the other classes with super(). I also think that a class can only extend one class.

class a:
    def __init__(self):
        print("initializing a")
class b(a):
    def __init__(self):
        print("initializing b")
        super().__init__()
class c(b):
    def __init__(self):
        print("initializing c")
        super().__init__()
e=c()

Now it calls each constructors when creating e.

  • You can extend multiple classes perfectly fine. But yes, you need to use super(). – RemcoGerlich Mar 27 '23 at 18:02
  • Yes, I just found out about that. Then the super().__init__() calls both constructors – MukkuPretski Mar 27 '23 at 18:11
  • You also do not need to use `super()` (but it helps). And it does not call both constructors. It only calls the one that comes next in the method resolution order (MRO). – mkrieger1 Mar 27 '23 at 18:54