国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python類的多重繼承問題深入分析

2020-02-23 06:09:56
字體:
來源:轉載
供稿:網友

正文

首先得說明的是,Python的類分為經典類 和 新式類
經典類是python2.2之前的東西,但是在2.7還在兼容,但是在3之后的版本就只承認新式類了
新式類在python2.2之后的版本中都可以使用

經典類和新式類的區別在于:

經典類是默認沒有派生自某個基類的,而新式類是默認派生自object這個基類的:

代碼如下:
# old style
class A():pass

# new style
class A(obejct):pass

2.經典類在類多重繼承的時候是采用從左到右深度優先原則匹配方法的..而新式類是采用C3算法(不同于廣度優先)進行匹配的

3.經典類是沒有__MRO__和instance.mro()調用的,而新式類是有的.

為什么不用經典類,要更換到新式類

因為在經典類中的多重繼承會有些問題...可能導致在繼承樹中的方法查詢繞過后面的父類:

代碼如下:
class A():
    def foo1(self):
        print "A"
class B(A):
    def foo2(self):
        pass
class C(A):
    def foo1(self):
        print "C"
class D(B, C):
    pass

d = D()
d.foo1()

按照經典類的查找順序從左到右深度優先的規則,在訪問d.foo1()的時候,D這個類是沒有的..那么往上查找,先找到B,里面沒有,深度優先,訪問A,找到了foo1(),所以這時候調用的是A的foo1(),從而導致C重寫的foo1()被繞過.

所以python引入了新式類的概念,每個基類都繼承自object并且,他的匹配規則也從深度優先換到了C3

C3算法

C3算法是怎么做匹配的呢..在問答版塊上面討論之后,歸結如下:

C3算法的一個核心是merge.

在merge列表中,如果第一個序列mro的第一個類是出現在其它序列,并且也是第一個,或者不出現其它序列,那么這個類就會從這些序列中刪除,并合到訪問順序列表中
比如:(引用問題中zhuangzebo的回答@zhuangzebo)

代碼如下:
class A(O):pass
class B(O):pass
class C(O):pass
class D(A,B):pass
class E(C,D):pass

首先需要知道 O(object)的mro(method resolution order)列表是[O,]
那么接下來是:

代碼如下:
mro(A) = [A, O]
mro(B) = [B, O]
mro(C) = [C, O]
mro(D) = [D] + merge(mro(A), mro(B), [A, B])
= [D] + merge([A, O], [B, O], [A, B])
= [D, A] + merge([O], [B, O], [B])
= [D, A, B] + merge([O], [O])
= [D, A, B, O]
mro(E) = [E] + merge(mro(C), mro(D), [C, D])
= [E] + merge([C, O], [D, A, B, O], [C, D])
= [E, C] + merge([O], [D, A, B, O], [D])
= [E, C, D] + merge([O], [A, B, O])
= [E, C, D, A, B] + merge([O], [O])
= [E, C, D, A, B, O]

然后還有一種特殊情況:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄梅县| 荔浦县| 武城县| 专栏| 永宁县| 永胜县| 偃师市| 黔东| 荥经县| 新民市| 樟树市| 济源市| 吴旗县| 襄垣县| 阳曲县| 宁陕县| 孟州市| 平舆县| 澎湖县| 城口县| 海门市| 雷波县| 林周县| 农安县| 县级市| 永靖县| 开远市| 台北县| 安庆市| 山东省| 淄博市| 玉田县| 轮台县| 东阿县| 离岛区| 利川市| 商丘市| 青海省| 涞源县| 景宁| 陇南市|