我正在阅读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 |
                          ---


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


  懒惰的程序员可以直接从Python 2.2获取MRO,因为
  在这种情况下,它与Python 2.3线性化一致。

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



我感到困惑的原因是在文章的前面已经说过:


  经典类保持其旧方法的解析顺序,深度
  首先,然后从左到右。


问题:如果旧式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种:


经典类方法解析。
Python 2.2新型类方法解析。
Python 2.3+ C3线性化。


对于给定的示例,方案2和方案3将产生相同的MRO。

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

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

10-15 08:00
查看更多