内容简介:Python在2.3之后引入了新的继承方式,同时也带来了新的假设我们有一个类,叫C,他们继承自B1, B2, B3, ..., BN生成MRO的规则如下:
MRO
Python在2.3之后引入了新的继承方式,同时也带来了新的 MRO - the C3 method resolution order
。
为啥用英文呢,因为我不知道中文是啥。另外鉴于不是讲历史,所以我们只介绍 C3 MRO
。
假设我们有一个类,叫C,他们继承自B1, B2, B3, ..., BN
生成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.
我们用 L[C]
来表示C的MRO:
L[C] = C + merge(L[B1], L[B2], ..., L[BN], B1...BN) 如果C是object的话,停止搜索
取 L[B1]
中的第一个结果,然后看看是否在后续列表的tail中,如果不在,那就把它加到
结果里(并且从所有列表中移除它),否则,就看 L[B2]
的第一个结果,如此循环。
我们来定义一下tail: tail 就是取列表中除去第一个之后的所有元素,例如 [1, 2, 3] 的tail就是 [2, 3];相反,head就是第一个元素,例如上面的例子,head是 1。
接下来我们来举例子:
>>> O = object >>> class F(O): pass >>> class E(O): pass >>> class D(O): pass >>> class C(D,F): pass >>> class B(D,E): pass >>> class A(B,C): pass
画成ASCII表示:
6 --- Level 3 | O | (more general) / --- \ / | \ | / | \ | / | \ | --- --- --- | Level 2 3 | D | 4| E | | F | 5 | --- --- --- | \ \ _ / | | \ / \ _ | | \ / \ | | --- --- | Level 1 1 | B | | C | 2 | --- --- | \ / | \ / \ / --- Level 0 0 | A | (more specialized) ---
我们先来计算他们各自的MRO:
L[O] = O 因为他是object自己 L[D] = D O L[E] = E O L[F] = F O
B的MRO为:
L[B] = B + merge(L[D], L[E], DE)
也就是 L[B] = B + merge(DO, EO, DE)
首先我们取 DO
里的 D
,它不在后面串里的tail部分,所以它会被加入到MRO中,
并且会从后面的列表中去掉。
L[B] = B + D + merge(O, EO, E)
然后我们进行下一步,选择 O
,但是发现它存在于后面的列表中, EO
包含了它。
所以跳过 O
。选择 E
:
L[B] = B + D + E + merge(O, O)
也就是 L[B] = B + D + E + O
我们写成
L[B] = B D E O
同样我们来算 L[C]
:
L[C] = C + merge(DO, FO, DF) = C + D + merge(O, FO, F) = C + D + F + merge(O, O) = C D F O
然后我们算 L[A]
:
L[A] = A + merge(BDEO,CDFO,BC) = A + B + merge(DEO,CDFO,C) = A + B + C + merge(DEO,DFO) = A + B + C + D + merge(EO,FO) = A + B + C + D + E + merge(O,FO) = A + B + C + D + E + F + merge(O,O) = A B C D E F O
所以最后我们调用 A.a_method
的寻找顺序就是 A B C D E F O
。
我们来验证一下:
In [1]: O = object In [2]: class F(O): pass In [3]: class E(O): pass In [4]: class D(O): pass In [5]: class C(D, F): pass In [6]: class B(D, E): pass In [7]: class A(B, C): pass In [8]: A.__mro__ Out[8]: (__main__.A, __main__.B, __main__.C, __main__.D, __main__.E, __main__.F, object) In [9]:
应用
利用 Python 的多继承,我们可以使用 Mixin
。这是啥呢,就是相当于一个补丁,比如:
class Parent(object): internal_str = "from internal" def foo(self): print("foo", self.internal_str) def bar(self): print("bar", self.internal_str) class FooMixin(object): def foo(self): print("FooMixin.foo, and Parent's internal_str is %s" % self.internal_str) class Son(FooMixin, Parent): pass Son().foo() Son().bar()
[email protected] (master): python test.py FooMixin.foo, and Parent's internal_str is from internal bar from internal
FooMixin中没有 internal_str
但是也能正常打印。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
MySQL技术内幕
姜承尧 / 机械工业出版社 / 2013-5 / 79.00元
《MySQL技术内幕:InnoDB存储引擎(第2版)》由国内资深MySQL专家亲自执笔,国内外多位数据库专家联袂推荐。作为国内唯一一本关于InnoDB的专著,《MySQL技术内幕:InnoDB存储引擎(第2版)》的第1版广受好评,第2版不仅针对最新的MySQL 5.6对相关内容进行了全面的补充,还根据广大读者的反馈意见对第1版中存在的不足进行了完善,《MySQL技术内幕:InnoDB存储引擎(第2......一起来看看 《MySQL技术内幕》 这本书的介绍吧!