-- 每個類的繼承順序都是從基類向子類看 -- 造成一個指向關係的順序[當前類] + [父類的繼承順序] -- 進行一個提取 -- 若是一個類出現從左到右的第一個順序上,而且沒有出如今後面的順序中,或者出如今後面順序了,可是仍然是第一個,那麼就把這個類提取出來
# 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 '''
# 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 '''
看代碼,請說出執行流程python
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 '''
首先觀察代碼,畫出繼承順序圖算法
那麼這裏爲何要用到c3算法,就是爲了算出mro順序(這裏只能手推,不能打印)。當算出來mro順序以後,咱們就能夠在後面用到了。ide
''' 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 '''
一番推算,mro的順序爲FEBCDAO。spa
接下來,咱們開始解釋代碼的執行流程。3d
''' 先把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 allcode