手推C3算法

C3算法规则

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

示例1

# class A(object): ...
# class B(A): ...
# class C(A): ...
# class D(B, C): ...
# print(D.__mro__)  # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
'''手推mro,从上至下的顺序
L(A) = [A] + [O]
A = [0]
A0 = []
L(A) = AO

L(B) = [B] + [A0]
B = [AO]
BA = [O]
BAO = []
L(B) = BAO

L(C) = [C] + [AO]
C = [AO]
CA = [0]
CAO = []
L(C) = CAO

L(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  (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.F'>, <class 'object'>)
'''手推C3算法
L(G) = [G] + [O]
G = [O]
GO = []
L(G) = GO

L(E) = [E] + [G0]
E = [GO]
EG = [O]
EGO = []
L(E) = EGO

L(D) = [D] + [DO]
D = [O]
DO = []
L(D) = DO

L(F) = [F] + [FO]
F = [O]
FO = []
L(F) = FO

L(B) = [B] + [DO] + [EGO]
B = [DO] + [EGO]
BD = [O] + [EGO]
BDE = [O] + [GO]
BDEG = [O] + [O]
BDEGO = []
L(B) = BDEGO

L(C) = [C] + [DO] + [FO]
C = [DO] + [FO]
CD = [O] + [FO]
CDF = [O] + [O]
CDFO = []
L(C) = CDFO

L(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 (<class '__main__.F'>, <class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
33 # 打印结果如下示例
34 '''
35 enter F
36 enter E
37 enter B
38 leave B
39 enter C
40 enter D
41 enter A
42 leave A
43 leave D
44 leave C
45 leave E
46 enter D
47 enter A
48 leave A
49 leave D
50 leave F
51 '''
demo
解:

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

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

'''

L(A) = [A] + [O]
A = [0]
AO = []
L(A) = AO

L(B) = [B] + [O]
B = [O]
BO = []
L(B) = BO

L(C) = [C] + [AO]
C = [AO]
CA = [O]
CAO = []
L(C) = CAO

L(D) = [D] + [AO]
D = [AO]
DA = [O]
DAO = []
L(D) = DAO

L(E) = [E] + [BO] + [CAO]
E = [BO] + [CAO]
EB = [O] + [CAO]
EBC = [O] + [AO]
EBCA = [O] + [O]
EBCAO = []
L(E) = EBCAO

L(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的继承顺序,放这里:FEBCDAO
1. 代码从第F()开始执行,执行其内部的init方法首先打印enter F
2. 执行E中的init方法,打印一行enter E
3. 执行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 F
enter E
enter B
leave B
enter C
enter D
enter A
leave A
leave D
leave C
leave E
enter D
enter A
leave A
leave D
leave F
'''

 


that's all

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值