我們知道python中的類與類之間是可以相互繼承的。在繼承關(guān)系中万皿,子類自動(dòng)擁有父類中除了私有屬性之外的其他所有內(nèi)容。python中支持多繼承牢硅,也就是說一個(gè)類可以有多個(gè)父類芝雪。但是在多繼承中减余,存在這樣一個(gè)問題:當(dāng)兩個(gè)父類中出現(xiàn)重名方法的時(shí)候惩系,如何處理他們的繼承關(guān)系,即MRO(method resolution order)方法解析順序問題堡牡。
Python2中的MRO
在python2中存在兩種類:
- 經(jīng)典類:在python2.2之前。一直使用的是經(jīng)典類晤柄。經(jīng)典類的根如果什么都不寫,表示繼承XXX芥颈。
- 新式類:在python2.2之后出現(xiàn)了新式類。新式類的特點(diǎn)是基類的根是object
Python3中的MRO
- python3中使用的都是新式類爬坑。如果基類誰都不繼承纠屋,那么這個(gè)類會(huì)默認(rèn)繼承object盾计。
本文只講述Python3新式類的MRO
計(jì)算公式L[C(B)] = C + merge(L[B],B) = C + L[B]
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E(C, A):
pass
class F(D, E):
pass
class M:
pass
class N(M):
pass
class P(E, A):
pass
class X:
pass
class Q(P,N,X):
pass
class G(Q, F):
pass
class H(G, F):
pass
L(H) = H + L(G) + L(F) + GF => H + GQPFDBECANMX + FDBECA + GF => HGQPFDBECANMX
L(G) = G + L(G) + L(F) + QF => GQPFDBECANMX
L(Q) = Q + L(P) + L(N) + L(X) + PNX => QPECANMX
L(X) = X => X
L(P) = P + L(E) + L(A) + EA => PECA
L(N) = N + L(M) + M => NM
L(M) = M => M
L(F) = F + L(D) + L(E) + DE => FDBECA
L(E) = E + L(C) + L(A) + CA => ECA
L(D) = D + L(B) + L(C) + BC => DBCA
L(C) = C + L(A) + A => CA
L(B) = B + L(A) + A => BA
L(A) = A => A
求H的MRO
設(shè)求MRO的算法是L
加法:merge(), 拿第一項(xiàng)的第一位和 后面每項(xiàng)的除了第一位比較. 如果沒有出現(xiàn), 則該位元素算出
如果出現(xiàn)了. 此時(shí)開始下一項(xiàng)的第一位繼續(xù)和后面每一項(xiàng)的除了第一位比較:
用頭和后面身體比較
上面的是手工算的MRO,其實(shí)在python中可以使用類名.mro(H.__mro__
)的方式直接輸出對(duì)應(yīng)類的MRO署辉。
(<class '__main__.H'>, <class '__main__.G'>, <class '__main__.Q'>, <class '__main__.P'>,
<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>,
<class '__main__.C'>, <class '__main__.A'>, <class '__main__.N'>, <class '__main__.M'>,
<class '__main__.X'>, <class 'object'>)