python - 对于旧式和新式,该类层次结构的 MRO 是否相同?

标签 python multiple-inheritance method-resolution-order

我正在阅读Python 2.3 MRO文章,其中给出了以下类层次结构:

>>> O = object
>>> class F(O): pass
>>> class E(O): pass
>>> class D(O): pass
>>> class C(D,F): pass
>>> class B(E,D): pass
>>> class A(B,C): pass

                           6
                          ---
Level 3                  | O |
                       /  ---  \
                      /    |    \
                     /     |     \
                    /      |      \
                  ---     ---    ---
Level 2        2 | E | 4 | D |  | F | 5
                  ---     ---    ---
                   \      / \     /
                    \    /   \   /
                     \  /     \ /
                      ---     ---
Level 1            1 | B |   | C | 3
                      ---     ---
                       \       /
                        \     /
                          ---
Level 0                0 | A |
                          ---

在其后面的段落中,以下引用让我感到困惑:

A lazy programmer can obtain the MRO directly from Python 2.2, since in this case it coincides with the Python 2.3 linearization.

>>> A.mro()
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>,
<class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>,
<type 'object'>)

我感到困惑的原因是文章前面提到:

Classic classes maintain their old method resolution order, depth first and then left to right.

问题:如果旧式MRO是深度优先、从左到右,那么上述类层次结构的旧式MRO应该是不同的,即ABEODOCDOFO。因此,“懒程序员”无法直接从Python 2.2获取其MRO。是这样吗?

例如,在以下代码片段中(不要在 Python 3.x 上运行它):

class O: 
    x = 'o'
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): 
    x = 'c'
class B(E,D): pass
class A(B,C): pass

print A.x

如果旧式 MRO 与新式 MRO 相同(即 ABEC 等),我希望它打印 c。但是,它会打印 o (即 ABEO 等)。

或者在这里:

class O: pass
class F(O): pass
class E(O): pass
class D(O):
    x = 'd'
class C(D,F): 
    x = 'c'
class B(E,D): pass
class A(B,C): pass

print A.x

如果旧式 MRO 与新式 MRO 相同(即 ABEC 等),我希望它打印 c。但是,它会打印 d (即,它是 ABEOD 等)。

我是 Python 新手,所以我想我错过了一些东西?

最佳答案

问题是,无论是在 Python 2.2、2.3 还是更高版本中,这些都是新式类。这里有3个方法解析方案,而不是2个:

  1. 经典类方法解析。
  2. Python 2.2 新式类方法解析。
  3. Python 2.3+ C3 线性化。

方案 2 和 3 将为给定示例生成相同的 MRO。

如果你想查看(现在几乎完全不相关的)Python 2.2 方法解析方案,最完整的文档可能是 a blog post来自 Guido 的旧 Python 历史博客。还有一个old archived draft Python 2.2 的文档,其中大部分描述了它,但没有提及特殊情况。

关于python - 对于旧式和新式,该类层次结构的 MRO 是否相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49614553/

相关文章:

python - 新型类中的方法解析顺序(MRO)?

c# - 从方法签名中删除通用参数

python - 隐式调用父类初始化器

python - 拼写错误 - Pyenchant

python - 在使用用 PL/Python 编写的 bool 存储过程的 PostgreSQL CHECK 约束中,可以更新错误消息的详细信息吗?

java - 过滤器/组件模式而不是笨拙的继承?

c++ - 没有多重继承的指针调整

python - 使用 Selenium WebDriver 和 Python 检索动态框架名称?

python - 复杂的列表理解与 Python 中的许多循环

python - 结合多重继承使用元类的类型错误