博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手推C3算法
阅读量:5055 次
发布时间:2019-06-12

本文共 4035 字,大约阅读时间需要 13 分钟。

C3算法规则

-- 每一个类的继承顺序都是从基类向子类看-- 形成一个指向关系的顺序[当前类] + [父类的继承顺序]-- 进行一个提取-- 如果一个类出现从左到右的第一个顺序上,并且没有出现在后面的顺序中,或者出现在后面顺序了,但是仍然是第一个,那么就把这个类提取出来

示例1

# class A(object): ...# class B(A): ...# class C(A): ...# class D(B, C): ...# print(D.__mro__)  # (
,
,
,
,
)'''手推mro,从上至下的顺序L(A) = [A] + [O]A = [0]A0 = []L(A) = AOL(B) = [B] + [A0]B = [AO]BA = [O]BAO = []L(B) = BAOL(C) = [C] + [AO]C = [AO]CA = [0]CAO = []L(C) = CAOL(D) = [D] + [BAO] + [CAO]D = [BAO] + [CAO]DB = [AO] + [CAO]DBC = [AO] + [AO]DBCA = [O] + [O]DBCAO = []L(D) = DBCA0'''

示例2

# class G(object): ...# class E(G): ...# class D(object): ...# class F(object): ...# class B(D, E): ...# class C(D, F): ...# class A(B, C): ...# print(A.__mro__)  #  ABCDEGFO  (
,
,
,
,
,
,
,
)'''手推C3算法L(G) = [G] + [O]G = [O]GO = []L(G) = GOL(E) = [E] + [G0]E = [GO]EG = [O]EGO = []L(E) = EGOL(D) = [D] + [DO]D = [O]DO = []L(D) = DOL(F) = [F] + [FO]F = [O]FO = []L(F) = FOL(B) = [B] + [DO] + [EGO]B = [DO] + [EGO]BD = [O] + [EGO]BDE = [O] + [GO]BDEG = [O] + [O]BDEGO = []L(B) = BDEGOL(C) = [C] + [DO] + [FO]C = [DO] + [FO]CD = [O] + [FO]CDF = [O] + [O]CDFO = []L(C) = CDFOL(A) = [A] + [BDEGO] + [CDFO]A = [BDEGO] + [CDFO]AB = [DEGO] + [CDFO]ABC = [DEGO] + [DFO]ABCD = [EGO] + [FO]ABCDE = [GO] + [FO]ABCDEG = [O] + [FO]ABCDEGF = [O] + [O]ABCDEGFO = []L(A) = ABCDEGFO'''

应用

看代码,请说出执行流程

1 class A(object): 2     def __init__(self): 3         print("enter A") 4         print("leave A") 5 class B(object): 6     def __init__(self): 7         print("enter B") 8         print("leave B") 9 class C(A):10     def __init__(self):11         print("enter C")12         super().__init__()13         print("leave C")14 class D(A):15     def __init__(self):16         print("enter D")17         super().__init__()18         print("leave D")19 class E(B, C):20     def __init__(self):21         print("enter E")22         B.__init__(self)23         C.__init__(self)24         print("leave E")25 class F(E, D):26     def __init__(self):27         print("enter F")28         E.__init__(self)29         D.__init__(self)30         print("leave F")31 F()32 # print(F.__mro__)  # FEBCDA0 (
,
,
,
,
,
,
)33 # 打印结果如下示例34 '''35 enter F36 enter E37 enter B38 leave B39 enter C40 enter D41 enter A42 leave A43 leave D44 leave C45 leave E46 enter D47 enter A48 leave A49 leave D50 leave F51 '''
demo

解:

首先观察代码,画出继承顺序图

那么这里为什么要用到c3算法,就是为了算出mro顺序(这里只能手推,不能打印)。当算出来mro顺序之后,我们就可以在后面用到了。

'''L(A) = [A] + [O]A = [0]AO = []L(A) = AOL(B) = [B] + [O]B = [O]BO = []L(B) = BOL(C) = [C] + [AO]C = [AO]CA = [O]CAO = []L(C) = CAOL(D) = [D] + [AO]D = [AO]DA = [O]DAO = []L(D) = DAOL(E) = [E] + [BO] + [CAO]E = [BO] + [CAO]EB = [O] + [CAO]EBC = [O] + [AO]EBCA = [O] + [O]EBCAO = []L(E) = EBCAOL(F) = [F] + [EBCAO] + [DAO]F = [EBCAO] + [DAO]FE = [BCAO] + [DAO]FEB = [CAO] + [DAO]FEBC = [AO] + [DAO]FEBCD = [AO] + [AO]FEBCDA = [O] + [O]FEBCDAO = []L(F) = FEBCDAO'''
手推C3算法,求出mro顺序

一番推算,mro的顺序为FEBCDAO。

接下来,我们开始解释代码的执行流程。

'''先把mro的继承顺序,放这里:FEBCDAO1. 代码从第F()开始执行,执行其内部的init方法首先打印enter F2. 执行E中的init方法,打印一行enter E3. 执行B中的init方法,打印enter B,紧接着打印leave B,执行完毕,代码回到E中4. 执行C中的init方法,打印enter C, 然后调用父类的super方法,    那该执行父类的init方法,这里要知道C的父类是谁?是A吗?(注意,关键点来了)    不是!而是顺着mro的顺序查找,C后面是D,所以,执行D的init方法    首先打印enter D, 接着D又执行super方法,找父类的super方法,mro中是A    所以执行A中的init方法,打印enter A,在打印leave A,然后,回到D中    又打印leave D,执行完毕,回到C中    打印leave C,执行完毕,回到E中    打印leave E,E此时也执行完毕,回到最开始的F中5. 执行D中init方法    首先打印enter D    调用父类的super方法,从mro找父类        打印enter A        打印leave A        A执行完毕,回到D中    打印leave D    执行完毕,回到最初F中6. 打印leave F,程序结束    enter Fenter Eenter Bleave Benter Center Denter Aleave Aleave Dleave Cleave Eenter Denter Aleave Aleave Dleave F'''

 


that's all

 

转载于:https://www.cnblogs.com/Neeo/p/10003881.html

你可能感兴趣的文章
ios开发- 利用运行时(runtime)字典转模型
查看>>
python基础(集合,文件操作)
查看>>
CSS Box Model 盒子模型
查看>>
Linux三剑客之awk最佳实践
查看>>
[译] Javascript初学者需要知道的十件事
查看>>
分糖果(模拟)
查看>>
linux命令,vim,vi 说明
查看>>
34 String、StringBuffer、StringBuilder
查看>>
LINUX下SYN攻防战 [转]
查看>>
C# 导出Word报”无法打开Office open xml文件。因为文件内容有错误“ 解决方法
查看>>
Linux内核_实验三:跟踪分析Linux内核的启动过程
查看>>
电脑是怎样识别USB3.0 U盘的
查看>>
Unity 捕获IronPython脚本错误
查看>>
word批量打印工具,c#写的
查看>>
Asp.Net MVC学习总结(一)——Asp.Net MVC简单入门
查看>>
Python学习第四篇——列表访问与判定
查看>>
JavaScript
查看>>
配置SVTI
查看>>
light oj 1138 - Trailing Zeroes (III)(阶乘末尾0)
查看>>
Windows如何自定义U盘盘符、文件夹图标、文件夹背景
查看>>