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

为什么在下面的代码中,MRO在python中是反向的?,python,method-resolution-order,Python,Method Resolution Order,输出为: 调用函数func 我有麻烦了 但是根据 顺序应为“深度优先左向右遍历”+“删除重复项,最后一次除外” 如/visionscaper(用户:889617)所述 为什么会有这种差异?当谈到遍历时,它首先从左到右搜索深度,直到找到为止。它调用它找到的第一个。就你而言: 它在C中搜索func,但没有找到它。向左走 它在A中搜索func——找到它。完成。打印我在一个中 重要的是A没有覆盖func。在这种情况下: 它在C中搜索func,但没有找到它。向左走 它在A中搜索func,但没有找到它。下

输出为:

调用函数func
我有麻烦了
但是根据

顺序应为“深度优先左向右遍历”+“删除重复项,最后一次除外”

如/visionscaper(用户:889617)所述


为什么会有这种差异?

当谈到遍历时,它首先从左到右搜索深度,直到找到为止。它调用它找到的第一个。就你而言:

  • 它在
    C
    中搜索
    func
    ,但没有找到它。向左走
  • 它在
    A
    中搜索
    func
    ——找到它。完成。打印
    我在一个
  • 重要的是
    A
    没有覆盖
    func
    。在这种情况下:

  • 它在
    C
    中搜索
    func
    ,但没有找到它。向左走
  • 它在
    A
    中搜索
    func
    ,但没有找到它。下降了,不对
  • 它在
    Z
    中搜索
    func
    ——在那里找到它。打印
    我在Z

  • 继承层次结构的深度优先从左到右遍历
    C
    将给出:
    [C,A,Z,B,Z]
    。因为Python不允许重复,所以第一个
    Z
    被删除,最后得到
    [C,A,B,Z]
    。因此,当调用
    C.func()
    时,可以从
    A
    获得实现。
    A.func
    中没有
    super
    调用,因此这是该行的结尾

    通过调用任何类的
    MRO
    方法,可以获取该类的完整MRO:

    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()
    

    在中,每个
    \uuuu init\uuuu
    方法通过使用
    super
    调用MRO中的下一个方法。但是,由于它们在打印自己的消息之前都进行了
    super
    调用,因此打印行的顺序最终与调用函数的顺序相反。您可以通过将
    print
    行与super调用交换,使
    print
    调用首先发生,从而使其与MRO的工作顺序相同。

    它的工作顺序完全是从左到右的深度优先。A是B的左边,作为C的父级。什么让你感到困惑?从C开始,深度优先从左到右遍历的下一个基类是C:A的最左边的基类。你期望什么?这里的查找顺序是A,Z,B(从B层次结构中删除A,Z作为重复项)物理学家:你的命令是错误的<代码>B
    必须出现在MRO中的
    Z
    之前。也可以完成:直接跳到B,跳过A,Z作为重复项。检查实例字典。引发属性错误。第二种方案完全错误。如果
    A
    没有实现
    func
    ,那么将调用
    B
    的版本。
    C
    的MRO为
    C、A、B、Z
    Z
    在任何MRO中都不会出现在
    B
    之前,因为它是
    B
    的父项。啊,是的,我明白了,你是对的。这就是我没有测试我写的东西所得到的。嗨,Blckknght,谢谢你消除了我的疑虑。实际上,当我在上面的例子中使用超级功能时,我感到困惑。你提到的线索是正确的,“我想你指的答案”也感谢其他人,他们试图消除我的疑虑。
    >>> C.mro()
    [__main__.C, __main__.A, __main__.B, __main__.Z, object]