Python 的继承

栏目: Python · 发布时间: 5年前

内容简介: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 但是也能正常打印。

Python 2.3 MRO


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

DOOM启世录

DOOM启世录

[美] 大卫·卡什诺 / 孙振南 / 电子工业出版社 / 2004-4 / 29.00元

由David Kushner 撰写之著作 《Master of DOOM》在 Amazon 和 eBook上的销售喜人。本书的中文版权由我公司拿到,将在2004年4月出版。本书忠实详尽地讲述了两个玩家是如何走上游戏之路,如何制作出迄今为止影响力最大的游戏作品--DOOM和Quake,以及他们为何在最辉煌的时候分道扬镳。本书是国内第一部游戏领域的传记。与所有传记一样,不同的读者能从中得到不同的体验:......一起来看看 《DOOM启世录》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码