Python 3.1:C3 方法解析顺序 [英] Python 3.1: C3 method resolution order

查看:55
本文介绍了Python 3.1:C3 方法解析顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个非常简单的菱形继承案例:

A very simple case of diamond-type inheritance:

class Root:
    def f(self):
        print('Root')

class A(Root): pass

class B(Root):
    def f(self):
        print('B')

class AB(A, B): pass

AB().f()

根据 Python 3.1.2 文档:

对于大多数目的,以最简单的方式情况下,您可以考虑搜索从父级继承的属性分类为深度优先,从左到右,不在同一班级中搜索两次哪里有重叠层次结构.

For most purposes, in the simplest cases, you can think of the search for attributes inherited from a parent class as depth-first, left-to-right, not searching twice in the same class where there is an overlap in the hierarchy.

因此,我希望我的示例按以下顺序解析:AB -> A -> Root -> B.但事实并非如此.使用 ActiveState Python 3.1.2,输出是B"而不是Root".

Hence, I expect my example to resolve in the order: AB -> A -> Root -> B. But it doesn't. Using ActiveState Python 3.1.2, the output is 'B' rather than 'Root'.

我错过了什么?

此外,我注意到 ActiveState Python 2.6 使用相同的代码打印Root".2.6 和 3.1 之间的解析规则有变化吗?

Also, I noticed that ActiveState Python 2.6 prints 'Root' with the same code. Did the resolution rules change between 2.6 and 3.1?

推荐答案

Python 2.6 打印了 Root 因为 Root 是一个旧样式的类.如果 Root 继承自 object(使其成为新样式的类),它应该打印 B.

Python 2.6 printed Root because Root is an old-style class. It should print B if Root inherits from object (making it a new-style class).

旧样式类不使用 C3 MRO,而是使用旧的有缺陷的 MRO,这正是您引用的文本所描述的.

Old style class doesn't use the C3 MRO, but the old flawed MRO, which is exactly what your quoted text describes.

B 出现在 Root 之前的原因是 B 也继承自 Root.

The reason B appears before Root is because B inherits from Root also.

AB的继承图为:

 AB - A - Root -- object
    \   /
      B

所以:

mro(object) = [object]
mro(Root)   = [Root] + mro(object)   # mro of single-inherited class is simple...
            = [Root, object]
mro(A)      = [A, Root, object]
mro(B)      = [B, Root, object]

在多重继承的情况下,MRO 是通过从左到右取超类 MRO 中的元素来计算的,不会出现在中间.在示例中更好地解释:

in case of multiple inheritance, the MRO is computed by taking the elements in the superclass's MROs from left to right, that doesn't appear in the middle. Better explained in example:

mro(AB) = [AB] + merge(mro(A), mro(B))
        = [AB] + merge([A, Root, object], [B, Root, object])   
        = [AB] + [A] + merge([Root, object], [B, Root, object])
           # A appears at head, pop it.
        = [AB] + [A] + [B] + merge([Root, object], [Root, object])
           # cannot pop Root because Root is not at head of [B, Root, object]
           # pop B instead.
        = [AB] + [A] + [B] + [Root] + merge([object], [object])
           # now we can pop Root because it only appears at the head position
        = [AB] + [A] + [B] + [Root] + [object]
        = [AB, A, B, Root, object] 

更多细节可以在 http://www.python.org/download 中找到/releases/2.3/mro/.

这篇关于Python 3.1:C3 方法解析顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆