关于python:如果在层次结构中混合新旧样式类会发生什么?

What happens if you mix old and new style classes in a hierarchy?

假设你有

1
2
3
4
5
class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass

当您具有混合层次结构时,相对于继承和方法解析顺序,Python的行为如何?它是否遵循旧的遍历,新的遍历,这两种遍历的混合,取决于层次结构的哪个分支在行走?


答案是"二者的混合"。您可以使用inspect.getmro()来检查自己,它既适用于旧样式类,也适用于新样式类。它返回MRO,即方法解析顺序。

任何旧样式类都有一个MRO,它是深度优先的,从第一个到最后一个。(对于最复杂的情况,这是一个坏主意,但保持向后兼容性。)我们可以这样表达它,这是因为已经计算了所有父类的MRO:

1
 mro(new_class) = [new_class] + mro(first_base) + mro(second_base) + ...

对于新类型的类,该算法使用相同的基本思想,但更为复杂——它也从[new_class]开始,但随后更巧妙地合并了mro(first_base)mro(second_base)等列表。

无论这些基类中的每一个是旧样式还是新样式,它们都已经有了自己的MRO,并且这些MRO(作为列表)是用于计算新类的MRO的唯一东西。


来自文档:

the linearization of C is the sum of C plus the merge of the
linearizations of the parents and the list of the parents.

这将意味着它取决于它当前所走的层次结构的哪个分支(即它是一个混合分支)。

它必须递归进行,这样我就不会期望不同的行为。