为什么这是一个模棱两可的 MRO?

Why is this an ambiguous MRO?

class First(object):
    def __init__(self):
        print("first")

class Second(First):
    def __init__(self):
        print("second")

class Third(First, Second):
    def __init__(self):
        print("third")

Source

为什么不能 Python 创建一致的 MRO?在我看来很清楚:

  1. 如果方法在第三个中不存在,则在第一个中搜索
  2. 如果方法在第一个中不存在,则在第二个中搜索

但如果你尝试一下:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases First, Second

要成为 "consistent",MRO 应满足以下限制条件:

  1. 如果一个class继承自多个超classes,它在superclass列表中较早列出的那些在MRO中应该比它较晚列出的那些更早。
  2. MRO 中的每个 class 都应该在它的任何超级 class 之前出现。

您提议的层次结构没有任何可能的顺序满足这些限制。因为 Third 被定义为从 First before Second 继承,所以在 MRO 中 First 应该在 Second 之前。但是因为 Second 继承自 First,所以在 MRO 中 Second 应该在 First 之前。这个矛盾无法调和。

您可以详细了解 Python 用于计算 MRO 的精确方法,称为 C3 linearization algorithm

如果我们应用C3线性化算法:

i) 取第一个列表的头部。

ii) 如果这个头部不在任何其他列表的尾部,则将其添加到 C 的线性化中,并将其从合并中的列表中删除

iii) 否则看下一个表的头,是好头就拿

iv) 然后重复该操作,直到所有class被移除或者找不到好的头

O : 是对象 class

L[第一个]=第一个O

L[第二] = 第二 + 合并(L[第一], 第一)

现在求解L[第二个]

L[Second] = Second + merge(FirstO, First)

First是列表FirstO中的头,在列表First中,所以是个好头。

L[第二个]=第二个+第一个+合并(O)

O是列表中唯一的头,它是好头

L[第二个]=第二个+第一个+O

L[第二] = 第二个第一个 O

L[Third] = Third + merge(L[First], L[Second], FirstSecond)

现在求解L[Third]

L[Third] = Third + merge(FirstO, SecondFirstO, FirstSecond)

L[第三] = 第三 + 找不到好头。

First 是列表 FirstO 中的头部,但它是列表 SecondFirstO 中的尾部,Second 是列表 SecondFirstO 中的头部,但它是列表 FirstSecond 中的尾部,O 是列表 FirstO 中的尾部, SecondFirstO 所以不可能找到好的头。

Python 内部认为在 sub-class.

之前没有 super class

根据您的代码。扫描或加载 classes 后,Python 认为方法解析必须是:

Third -> Second -> First

这里,FirstSecond的超class。

但是在执行时,在检查 Third 之后它会遇到 First,它是 的超级 class第二.

因此出现类型错误。

class Third(First, Second): # Wrong
class Third(Second, First): # Correct