mro:为什么调用两个父项的方法?

mro: why are methods from both parent called?

我正在玩 类 以了解 mro 在 python3 中的工作原理。我得到了主要思想:方法从左到右解析,深度优先,如果有一个共同的父级,它在最后。

这里有一些看起来很简单的东西并不像我预期的那样:

class A(object):
    def f(self):
        print("calling A")
        print("A")


class B(A):
    def f(self):
        print("calling B")
        super(B, self).f()
        print("B")


class C(A):
    def f(self):
        print("calling C")
        super(C, self).f()
        print("C")


class D(B,C):
    def f(self):
        print("calling D")
        super(D, self).f()
        print("D")

d=D()
d.f()

现在,由于 mro 是 D -> B -> C -> A,我希望 super 调用 B.f 以便它打印:

calling D
calling B
calling A
A
B
D

但它实际上也调用了 C.f:

calling D
calling B
calling C
calling A
A        
C        
B        
D        

这是为什么?

我希望 C.f 不被调用的原因是因为 B 作为方法 f,解析应该停止。如果 C 没有继承自 A:

就是这种情况
class A(object):
    def f(self):
        print("calling A")
        print("A")


class B(A):
    def f(self):
        print("calling B")
        super(B, self).f()
        print("B")


class C():
    def f(self):
        print("calling C")
        super(C, self).f()
        print("C")


class D(B,C):
    def f(self):
        print("calling D")
        super(D, self).f()
        print("D")

d=D()
d.f()
# prints:
# calling D
# calling B
# calling A
# A        
# B        
# D        

我认为重要的是要提到 super 不调用 "parent-class" 而是调用 "next class in the MRO".

你自己说了,MRO 是 D -> B -> C -> A for D。因此 D.f 中的 super 将解析为 BB.f 中的 super 将解析为 C 最后 super in C.f 将解析为 A.

如果您需要更多信息,可以使用多种资源(对 super 的用途有不同的解释):