python多繼承的3C算法
有很多地方都說python多繼承的繼承順序,是按照深度遍歷的方式,其實python多繼承順序的算法,不是嚴格意義上的深度遍歷,而是基于深度遍歷基礎上優化出一種叫3C算法
python多繼承的深度遍歷
class C:def run(self):print("這個是C類的方法");pass;class A(C):# def run(self):# print("這個是A類的方法");pass;class B:def run(self):print("這個是B類的方法");class MainC(A,B):pass;# def run(self):# print("這個是子類的方法");m1 = MainC();
m1.run();
print(MainC.mro())
這段代碼輸出的結果就是
這個是C類的方法
[<class ‘main.MainC’>, <class ‘main.A’>, <class ‘main.C’>, <class ‘main.B’>, <class ‘object’>]
每個類如果沒有繼承其他類的話就默認繼承object這個基類
這個是比較正常的多繼承,然后是深度遍歷的方式
重復繼承的問題
基于上面改造一下
class C:def run(self):print("這個是C類的方法");pass;class A(C):# def run(self):# print("這個是A類的方法");pass;class B(C):def run(self):print("這個是B類的方法");class MainC(A,B):pass;# def run(self):# print("這個是子類的方法");m1 = MainC();
m1.run();
print(MainC.mro())
這個繼承順序就有意思了,main繼承A和B,A繼承C,B也繼承C,這就出現了重復繼承的問題,那這種情況python是如何決定繼承順序的呢
輸出結果:
這個是B類的方法
[<class '__main__.MainC'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
這個結果就出乎意料了,因為按照深度遍歷的方式的話,也應該繼承C再繼承B,但是卻不是這樣的
這個是因為python對于重復繼承的處理,按照這個繼承方式的話繼承順序是這樣的
mianC先繼承A,然后到查看C的情況,發現C同時被A和B繼承了,然后就先不處理,接著繼承B,然后看C的時候發現,沒有其他的繼承了,就接著繼承C
更加復雜的繼承
class F:def run(self):print("這個是F類的方法");pass;class G:def run(self):print("這個是G類的方法");pass;class E(F,G):def run(self):print("這個是E類的方法");pass;class C(E):def run(self):print("這個是C類的方法");pass;
class D(E):def run(self):print("這個是D類的方法");class A(C):# def run(self):# print("這個是A類的方法");pass;class B(D):def run(self):print("這個是B類的方法");class MainC(A,B):pass;# def run(self):# print("這個是子類的方法");m1 = MainC();
m1.run();
print(MainC.mro())
繼承順序:
[<class '__main__.MainC'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.F'>, <class '__main__.G'>, <class 'object'>]
這個就是跟復雜的多繼承了,但是只要用到上面說的邏輯去推理就知道繼承順序了
mainc先繼承A,然后看C,沒有被重復繼承,就繼承C,再看E,E被重復繼承了,先不處理,再從上面開始看,看B,沒有被重復繼承,再看D也沒有被重復繼承,直接繼承,再看E,也沒有其他的再繼承了就可以直接繼承,然后再看F,沒有重復繼承,就繼承,再到G
這個就是實際上python多繼承順序的算法,如果單純說是深度遍歷,其實是不對的
注意
盡量不要用多繼承,盡量不要用多繼承,盡量不要用多繼承
用多繼承會讓你的程序變得復雜又難讀,產生的bug也難查