探討 Python 的繼承衝突 - tsungjung411/python-study GitHub Wiki
繼承的衝突-範例一
class A:
def print(self):
print('call A.print()')
# end-of-def
# end-of-class
class B:
def print(self):
print('call B.print()')
# end-of-def
# end-of-class
class C1(A,B):
pass
# end-of-class
class C2(B,A):
pass
# end-of-class
c = C1()
c.print()
c = C2()
c.print()
print('\n呼叫順序:')
from pprint import pprint
pprint(C1.mro())
pprint(C2.mro())
執行結果:
call A.print()
call B.print()
呼叫順序:
[<class '__main__.C1'>,
<class '__main__.A'>,
<class '__main__.B'>,
<class 'object'>]
[<class '__main__.C2'>,
<class '__main__.B'>,
<class '__main__.A'>,
<class 'object'>]
說明:
- 越靠近 class 名稱,優先權最高
- class C1(A, B), A 距離 C1 最近,先呼叫 A 的 print 方法
- class C2(B, A), B 距離 C2 最近,先呼叫 B 的 print 方法
繼承的衝突-範例二
class A:
def print(self):
print('call A.print()')
# end-of-def
# end-of-class
class B(A):
def print(self):
print('call B1.print()')
# end-of-def
# end-of-class
class C(A):
pass
# end-of-class
class D1(B, C):
pass
# end-of-class
class D2(C,B):
pass
# end-of-class
d = D1()
d.print()
d = D2()
d.print()
print('\n呼叫順序:')
from pprint import pprint
pprint(D1.mro())
pprint(D2.mro())
執行結果:
call B1.print()
call B1.print()
呼叫順序:
[<class '__main__.D1'>,
<class '__main__.B'>,
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>]
[<class '__main__.D2'>,
<class '__main__.C'>,
<class '__main__.B'>,
<class '__main__.A'>,
<class 'object'>]
Python 3: 印出 MRO 的幾個方法
class A: pass
class B(A): pass
class C(A): pass
class D1(B,C): pass
class D2(C,B): pass
import pprint
pprint.pprint(D1.mro())
pprint.pprint(D2.mro())
import inspect
print(inspect.getmro(D1))
print(inspect.getmro(D2))
執行結果:
[<class '__main__.D1'>,
<class '__main__.B'>,
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>]
[<class '__main__.D2'>,
<class '__main__.C'>,
<class '__main__.B'>,
<class '__main__.A'>,
<class 'object'>]
(<class '__main__.D1'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
(<class '__main__.D2'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
一篇拓撲排序演算法的介紹,非常值得一看:
對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊(u,v)∈E(G),則u在線性序列中出現在v之前。通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。簡單的說,由某個集合上的一個偏序得到該集合上的一個全序,這個操作稱之為拓撲排序。
其他參考資料
關鍵字
- 方法解析順序, Method Resolution Order, MRO
- 繼承, inherit, inheritance