'Puzzle about super() method

I am trying to understand how the super() method works. Here is the sample code I am using:

class A(object):
    def __init__(self):
        self.n = 'A'

    def func(self):
        print('@A')
        self.n += 'A'


class B(A):
    def __init__(self):
        self.n = 'B'

    def func(self):
        print('@B')
        self.n += 'B'


class C(A):
    def __init__(self):
        self.n = 'C'

    def func(self):
        print('@C')
        super().func()
        self.n += 'C'


class D(C, B):
    def __init__(self):
        self.n = 'D'

    def func(self):
        print('@D')
        super().func()
        self.n += 'D'


print(D.mro())
d = D()
d.func()
print(d.n)

The correct output results are:

[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
DBCD

What I do not understand is why there is no A in the output? I thought when entering Class C, there is a super().func() which calls the func in Class A. However, it is not the case.

Can anyone help me understand this behavior?

Thank you!



Solution 1:[1]

super().func isn’t the parent’s func method – it’s the method of the next class in the MRO. No A appears because B’s func does not call super().func, so the chain stops at B.

Solution 2:[2]

super doesn't just call the parent class. It ensures that the classes in a multiple inheritance tree are called in the proper order.

In your case, the super in D calls C. The super in C calls B, but because B doesn't have a call to super, the chain breaks down.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LeopardShark
Solution 2 Tim Roberts