python面向對象進階-04菱形繼承問題

類的分類

新式類

繼承了object的類以及該類的子類,都是新式類
Python3中全部的類都是新式類python

經典類

沒有繼承object的類以及該類的子類,都是經典類
只有Python2中才有經典類算法

菱形繼承問題

若是繼承關係爲菱形結構,即子類的父類最後繼承了同一個類,那麼屬性的查找方式有兩種:code

經典類下:深度優先
廣度優先:廣度優先繼承

經典類:一條路走到黑,深度優先
新式類:不找多各種最後繼承的同一個類,直接去找下一個父類,廣度優先
我的偏向下面的這個理解數學

當出現了菱形繼承時,新式類,先深度,當遇到了共同父類時就廣度

而經典類,就是深度優先

當類是經典類時,多繼承狀況下,在要查找屬性不存在時,會按照深度優先的方式查找下去
當類是新式類時,多繼承狀況下,在要查找屬性不存在時,會按照廣度優先的方式查找下去class

不廢話, 上例子!!!test

class G(object):
    da
    #     print('from G')
    pass

print(G.__bases__)

class E(G):
    da
    #     print('from E')
    pass

class B(E):
    da
    #     print('from B')
    pass

class F(G):
    da
    #     print('from F')
    pass

class C(F):
    da
    #     print('from C')
    pass

class D(G):
    da
    #     print('from D')
    pass

class A(B, C, D):
    def test(self):
        print('from A')

obj = A()
(<class 'object'>,)
obj.test()  # A->B->E-C-F-D->G-object

mro()方法介紹

python究竟是如何實現繼承的,對於你定義的每個類,python會計算出一個方法解析順序(MRO)列表,這個MRO列表就是一個簡單的全部基類的線性順序列表,如:原理

print(A.mro())  # A.__mro__

for i in A.mro():
    print(i)

[<class 'main.A'>, <class 'main.B'>, <class 'main.E'>, <class 'main.C'>, <class 'main.F'>, <class 'main.D'>, <class 'main.G'>, <class 'object'>]
<class 'main.A'>
<class 'main.B'>
<class 'main.E'>
<class 'main.C'>
<class 'main.F'>
<class 'main.D'>
<class 'main.G'>
<class 'object'>object

爲了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類爲止。
而這個MRO列表的構造是經過一個C3線性化算法來實現的。咱們不去深究這個算法的數學原理,它實際上就是合併全部父類的MRO列表並遵循以下三條準則:
子類會先於父類被檢查
多個父類會根據它們在列表中的順序被檢查
若是對下一個類存在兩個合法的選擇,選擇第一個父類方法

相關文章
相關標籤/搜索