关于 super() 方法的困惑

Puzzle about super() method

我正在尝试了解 super() 方法的工作原理。这是我使用的示例代码:

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)

正确的输出结果是:

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

我不明白的是为什么输出中没有A?我以为在进入Class C时,有一个super().func()调用了Class A中的func。然而,事实并非如此。

谁能帮我理解这种行为?

谢谢!

super().func 不是父级的 func 方法——它是 MRO 中下一个 class 的方法。没有出现A是因为Bfunc没有调用super().func,所以链停在B.

不,每个 super().func() 调用都允许您在 的下一个 class 中调用 func self 的 MRO(这可能与当前 class 的 MRO 不同)。当您在 D 的实例上调用 C.func 时,您遵循 D 的 MRO 并看到在 C 之后出现 B.

B.func 不调用 super,因此链在那里结束,跳过 A。如果您希望 B.func 在多重继承情况下可用,它也需要调用 super().func(),就像其他 classes 一样。

super 不只是调用父 class。它确保以正确的顺序调用多重继承树中的 classes。

在你的例子中,D 中的 super 调用了 C。C 中的 super 调用了 B,但是因为 B 没有调用 super,链中断了下来。