为什么 MRO 在下面的代码中 python 是反向的?

why MRO is reverse in python in below code?

class Z():
    def func():
        print ("I'm in Z")
class A(Z):
    def func():
        print ("I'm in A")
class B(Z):
    def func():
        print ("I'm in B")

class C(A,B):
    pass
    #def func():
     #   print ("I'm in C")

ob1 = C

print ("Calling function func ")
ob1.func()

输出为:

Calling function func
I'm in A

但是根据How does Python's super() work with multiple inheritance?

顺序应该是 "depth-first left-to-right traversal" + "removing duplicates expect for the last"

如 /visionscaper(用户:889617)所述,

为什么会有这种差异?

在谈到遍历时,它首先搜索深度,从左到右,直到找到为止。它调用它找到的第一个。在你的情况下:

  1. 它在 C 中搜索 func - 没有找到。向左下。
  2. 它在 A 中搜索 func - 找到了。完毕。打印 I'm in A.

如果 A 没有覆盖 func,这很重要。在这种情况下:

  1. 它在 C 中搜索 func - 没有找到。向左下。
  2. 它在 A 中搜索 func - 没有找到。往下,不对。
  3. 它在 Z 中搜索 func - 在那里找到它。打印 I'm in Z.

继承层次结构的深度优先从左到右遍历 C 会得到:[C, A, Z, B, Z]。由于 Python 不允许重复,第一个 Z 被删除,你最终得到 [C, A, B, Z]。因此,当您调用 C.func() 时,您会从 A 获得实现。 A.func 中没有 super 个调用,所以该行到此结束。

您可以通过调用其 mro 方法获得任何 class 的完整 MRO:

>>> C.mro()
[__main__.C, __main__.A, __main__.B, __main__.Z, object]

the answer I think you were referring to中,每个__init__方法使用super调用MRO中的下一个方法。但是由于他们每个人都在打印自己的消息之前进行了 super 调用,所以打印行的顺序最终与调用函数的顺序相反。你可以让它以与MRO 通过将 print 行与超级调用交换,以便 print 调用首先发生。