As far as i know, super()
is used to call the methods overwritten in the subclass (like an overwritten __init__
in the subclass).
Also, i know that all python classes inherit from a special class called object
.
While studying OOP i ran into a weird example:
class A(object):
def __init__(self):
print('A.__init__')
super().__init__()
class B(object):
def __init__(self):
print('B.__init__')
super().__init__()
class C(A, B):
def __init__(self):
print('C.__init__')
super().__init__()
I understand most of this except...why does class A has a super().__init__()
? It's the parent class, it shouldn't need to inherit from anyone. And the special object
class doesn't do anything so i don't know why it would need it.
This is not the only case i have seen a super
in the parent class, in a previous question i made, a solution to aproblem involved it but i didn't understood it. I also can't find an easy explanation of this usage of super()
inheritance.
In simple terms...why would i need to use super()
in a parent class?
Consider the following example:
class A:
def __init__(self, a, **kwargs):
print('A.__init__ called')
self.a = a
super().__init__(**kwargs)
print('A.__init__ finished')
class B:
def __init__(self, b, **kwargs):
print('B.__init__ called')
self.b = b
super().__init__(**kwargs)
print('B.__init__ finished')
class C(A, B):
def __init__(self, c, **kwargs):
print('C.__init__ called')
self.c = c
super().__init__(**kwargs)
print('C.__init__ finished')
When you create a C
object, the output is as follows:
>>> C(a=1, b=2, c=3)
C.__init__ called
A.__init__ called
B.__init__ called
B.__init__ finished
A.__init__ finished
C.__init__ finished
<__main__.C object at 0x7fd15abcab70>
From the order that the __init__
methods are called, and the fact that they finish in reverse order, we can see that C.__init__
calls A.__init__
, which calls B.__init__
. That is, although A
has no explicit parent class (so its direct parent is object
), the super().__init__
call in A
actually calls B.__init__
.
This is because B
is the next class after A
in C
's method resolution order (MRO). The A
class needs to call super()
because although its superclass is object
, Python allows multiple inheritance, so A
cannot guarantee that it is the last class before object
in the MRO.
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
See Raymond Hettinger's article Python's super() considered super! for a more detailed explanation about the MRO and "cooperative multiple inheritance techniques".