python3类的继承详解_python3 多重继承机制
由于python中包含多重繼承機(jī)制,那么子類在多重繼承中,到底用的是哪一個超類的方法就是大家關(guān)心的問題,之前在查閱已有書籍無果后,只得去翻官方文檔與博客,終于得解,于是在此總結(jié)歸納。
全稱 方法解析順序(Method Resolution Order) 簡稱為 MRO 這個東西就是來解決多重繼承的解析問題的,如果一般只關(guān)心順序,不關(guān)心解析順序怎么來的話,只要用類下的__ mro __的特殊方法,即可得到解析順序鏈。
python3與python2.2之前的解析方法并不相同,至于原因嘛,往下看就知道了。
舉個例子:
繼承的例子
Python 2.2 進(jìn)行解析的順序可以看做 廣度優(yōu)先 ,該結(jié)構(gòu)在python2.2之前能夠正常解析為[F, A, B, X, Y]的解析鏈。
首先我們看下各個類中的方法解析順序:這里A,B只有一層父子繼承關(guān)系,根據(jù)繼承的左右順序容易得出繼承鏈,(python2.2)與C3這時效果相同,對于 A 來說,其搜索順序?yàn)?[A, X, Y];對于 B,其搜索順序?yàn)?[B, Y, X];
關(guān)鍵在對于 F的解析上,python2.2之前其搜索順序?yàn)?[F, A, B, X, Y]。
這樣的結(jié)果是否合理呢?
對于F的繼承順序python3如何求解呢?
為了方便展示算法邏輯,首先規(guī)定幾個約定:
1.[c1, c2, c3, c4 .... cN] 代表N個類的解析列表
2.c1 + [c2, c3, c4 .... cN] = [c1, c2, c3, c4 .... cN] #解析列表的拼接方式
3.head([c1, c2, c3, c4 .... cN]) = c1 #取一個列表的頭部
4.tail([c1, c2, c3, c4 .... cN]) = [c2, c3, c4 .... cN] #剔除掉列表頭部的剩余部分
那么就從下面這個公式中展開,就是對merge的操作遞歸
#假設(shè)類C繼承自父類b1 b2 b3,那么C的繼承鏈如下
L[c] = c + merge(L[b1], L[b2], L[b3], b1, b2, b3)
c3算法流程
1.取出merge中第一個列表K1
2.取出h = head(K1),遍歷后續(xù)解析列表中所有的tail(KN),若tail中沒有出現(xiàn)了h,就將h從merge中所有列表中清除,并循環(huán)2
3.若當(dāng)前的h不符合要求則替換下一個K
4.若merge中所有的類被清除則正常輸出繼承解析列表,否則則拋出異常
好了對于F來說我們一步步來推導(dǎo):
L[A] = [A, X, Y]
L[B] = [B, Y, X]
L[F] = F + merge(L[A], L[B] , A, B)
L[F] = F + merge([A, X, Y], [B, Y, X] , A, B)
這時讓我們開始跑merge
L[F] = [F,A] + merge([X, Y], [B, Y, X] , B) (1)
L[F] = [F,A,B] + merge([X, Y], [Y, X]) (2)
然而當(dāng)繼續(xù)往下執(zhí)行的時候C3算法會拋出異常
L[F] = [F,A,B] + merge([X, Y], [Y, X]) (3)
因?yàn)樗薪馕隽斜硪呀?jīng)遍歷完,但是merge中的類并沒有清除完成。
那么C3算法為何要這么設(shè)計(jì)?
仔細(xì)看由python2.2之前推導(dǎo)的繼承鏈我們會發(fā)現(xiàn),B 和 F 中 X、Y 的搜索順序是相反的!也就是說,當(dāng) B 被繼承時,它本身的繼承鏈竟然也發(fā)生了改變,這很容易導(dǎo)致不易察覺的大坑。
C3算法 秉承的原則是子類形成的繼承鏈,應(yīng)該能完整的繼承超類的繼承鏈,而不是對超類的繼承鏈進(jìn)行改造而適配子類的繼承鏈。因此python2.2在大量的多重繼承后會引發(fā)意想不到的BUG,而當(dāng)你的繼承鏈出現(xiàn)類似例子中的情況時,C3則會拋出異常,提前終止你的不當(dāng)繼承行為。以上是個人的一些理解,如有不對可以評論探討。
相關(guān)資料:
總結(jié)
以上是生活随笔為你收集整理的python3类的继承详解_python3 多重继承机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux编译安装nginx1.4.7版
- 下一篇: python根据文件名打标签_使用pyt