Python的多继承C3算法解析

  介绍

本篇文章给大家分享的是有关Python的多继承C3算法解析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

<强> Python多继承MRO

在Python2.1中,采用了经典类,使用深度优先算法解析。

Python2.2中,引入了新式类,使用深度优先算法和广度优先算法。

在Python2.3以后的版本中,经典类和新式类共存,使用了DFS算法和C3算法。

Python2中的经典类

class (对象):   ,,,通过

Python3的新式类

class 答:   ,,,通过

C3算法

计算,C3超类线性化是一个算法主要用来获取方法应该继承的顺序(“linearization")多重继承,并经常被称为方法解析顺序(MRO)。

这是维基百科中的定义,下面这张图是一张多继承的关系图:

 Python的多继承C3算法解析

那么这里的mro解析顺序是如何的呢?单纯看图很难得出答案。

C3线性算法的推导过程如下:

假设类C继承自父类B1,…Bn,类C的解析列表公式如下:

 Python的多继承C3算法解析

这个公式表明C的解析列表是通过对其所有父类的解析列表及其父类一起合并得到的。

<强>合并操作分为如下几个步骤:

1。选取合并中的第一个列表记为当前列表k .

2。令h=(K),如果h没有出现在其他任何列表的尾部(列表中除了第一个元素,其余的称之为尾巴)当中,那么将其加入类C的线性化列表中,并将其从合并中的所有列表移除,之后重复步骤2 .

3。否,则设置K为合并的下一个列表,重复2中的操作。

4。如果合并的所有类都被移除,则输出类创建成功,如果不能找到下一个h,则输出C类抛出异常。

<>强推导过程

我们用上面的那张图试一下推导出mro的解析顺序。

上面那张图转换为python代码如下:

转换成python代码

O =对象   class  (O):通过   class  B (O):通过   class  C (O):通过   class  D (O):通过   class  E (O):通过   class  K1 (A, B, C):通过   class  K2 (B, D, E):通过   class  K3 (D, A):通过   class  Z (K1, K2, K3):通过   print (Z.mro ())

<>强推导

L (K1),=, K1  +,合并(L L [A], [B], [C], (A, B, C))   ,,,,,=,K1  +,合并(L (A、O), L (B、O), L (C O) (A, B, C))   ,,,,,=,(K1,), +,合并(L [O], L (B、O), L (C O) (B, C))   ,,,,,=,(K1, A、B), +,合并(L L [O], [O], L (C O), (C))   ,,,,,=,(K1, A, B, C), +,合并(L L [O], [O], L [O])   ,,,,,=,(K1, A, B, C、O)   L (K2),=, (K2, D, B, E, O)   L (K3),=, (K3, D, A, O)   以上是K1、K2、K3的解析顺序   下面是Z的推导过程   L (Z),=, Z  +,合并(L (K1) + L (K2) + L (K3) (K1、K2、K3))   ,,,,=,Z  +,合并(L[]阿,K1, A, B, C + L (K2, D, B, E, O) + L (K3, D, A, O), (K1、K2、K3))   ,,,,=,(Z, K1), +,合并(L (A, B, C、O) + L (K2, D, B, E, O) + L (K3, D, A, O), (K2, K3))   ,,,,=,(Z, K1, K2), +,合并(L (A, B, C、O) + L (D、B, E, O) + L (K3, D, A, O), (K3))   ,,,,=,(Z, K1、K2、K3), +,合并(L (A, B, C、O) + L (D、B, E, O) + L (D, A O))   ,,,,=,(Z, K1、K2、K3 D], +,合并(L (A, B, C、O) + L (B, E, O) + L (A、O))   ,,,,=,(Z, K1、K2、K3 D, A], +,合并(L (A B C O) + L (B, E, O) + L (O))   ,,,,=,(Z, K1、K2、K3 D, A, B), +,合并(L (C O) + L (E, O) + L (O))   ,,,,=,(Z, K1、K2、K3 D, A, B, C), +,合并(L [O] + L (E, O) + L (O))   ,,,,=,(Z, K1、K2、K3 D, A, B, C, E, O)

我们得出的最终答案为:Z的解析顺序:Z→K1, K2→K3→D→一个→B→C→E→O

为了验证答案,我们在python中运行

打印(Z.mro ())

结果如下

[& lt; class  & # 39; __main__.Z& # 39;祝辞,,& lt; class  & # 39; __main__.K1& # 39;祝辞,,& lt; class  & # 39; __main__.K2& # 39;祝辞,,& lt; class  & # 39; __main__.K3& # 39;祝辞,,& lt; class  & # 39; __main__.D& # 39;祝辞,   & lt; class  & # 39; __main__.A& # 39;祝辞,& lt; class  & # 39; __main__.B& # 39;祝辞,& lt; class  & # 39; __main__.C& # 39;祝辞,& lt; class  & # 39; __main__.E& # 39;祝辞,& lt; class  & # 39;对象# 39;祝辞]

和我们推导的结果相同,这就是C3算法的流程。

Python的多继承C3算法解析