Because this is exactly what you have asked) Reed more info on c3 linearization. Short hint - super does not call parents method, instead it calls method, that corresponds to next class in linearized inheritance graph.
More specifically:
>>> D.mro()
0: [<class '__main__.D'>,
<class '__main__.B'>,
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>
]
This mro
thing is a list, through witch any method of class D
that delegates its behavior to parents (sort of speak) would be pushed any time you call it. So you call D().show()
- first it calls implementation of show
in D
, it does nothing but delegating this call further - to class B
. Class B
fist delegates this call to C
(see the mro list) which delegates it further to A
, which prints "A"
, then C
prints "C"
and then B
prints "B"
.
You might ask - why B
delegates to C
instead of A
(since B
extends A
, not C
). This actually done on purpose, for more info have a look on this great talk