1. 程式人生 > >多重繼承方法或屬性調用順序(MRO)

多重繼承方法或屬性調用順序(MRO)

span cep 其它 1.5 style images 學習 top highlight

參考摘選自這篇文章http://hanjianwei.com/2013/07/25/python-mro/

python2.3以後采用c3方法來確定方法解析順序

我們把類 C 的線性化(MRO)記為 L[C] = [C1, C2,…,CN]。其中 C1 稱為 L[C] 的頭,其余元素 [C2,…,CN] 稱為尾。如果一個類 C 繼承自基類 B1、B2、……、BN,那麽我們可以根據以下兩步計算出 L[C]:

  1. L[object] = [object]
  2. L[C(B1…BN)] = [C] + merge(L[B1]…L[BN], [B1]…[BN])

這裏的關鍵在於 merge,其輸入是一組列表,按照如下方式輸出一個列表:

  1. 檢查第一個列表的頭元素(如 L[B1] 的頭),記作 H
  2. H 未出現在其它列表的尾部,則將其輸出,並將其從所有列表中刪除,然後回到步驟1;否則,取出下一個列表的頭部記作 H,繼續該步驟。
  3. 重復上述步驟,直至列表為空或者不能再找出可以輸出的元素。如果是前一種情況,則算法結束;如果是後一種情況,說明無法構建繼承關系,Python 會拋出異常。

例1:技術分享

L[object] = [object]
L[D] = [D, object]
L[E] = [E, object]
L[F] = [F, object]
L[B] = [B, D, E, object]
L[C] = [C, D, F, object]
L[A] = [A] + merge(L[B], L[C], [B], [C])
     = [A] + merge([B, D, E, object], [C, D, F, object], [B], [C])
     = [A, B] + merge([D, E, object], [C, D, F, object], [C])
     = [A, B, C] + merge([D, E, object], [D, F, object])
     = [A, B, C, D] + merge([E, object], [F, object])
     = [A, B, C, D, E] + merge([object], [F, object])
     = [A, B, C, D, E, F] + merge([object], [object])
     = [A, B, C, D, E, F, object]




例2:
class A(object):
    def go(self):
        print "go A go!"
    def stop(self):
        print "stop A stop!"
    def pause(self):
        raise Exception("Not Implemented")

class B(A):
    def go(self):
        super(B, self).go()
        print "go B go!"

class C(A):
    def go(self):
        super(C, self).go()
        
print "go C go!" def stop(self): super(C, self).stop() print "stop C stop!" class D(B,C): def go(self): super(D, self).go() print "go D go!" def stop(self): super(D, self).stop() print "stop D stop!" def pause(self): print "wait D wait!"

d=D()
d.go()
D的__mro__為D,B,C,A,object
super的類型參數決定了在mro列表中的搜索起始位置,總是範圍該參數後續類型的成員。(摘選自雨痕的python學習筆記)
super(D,self).go()返回D後面的成員即B,B的go()又返回C,C的go()返回A,所以打印結果為
go A go!
go C go!
go B go!
go D go!



class A(object):
    def go(self):
        print "go A go!"
    def stop(self):
        print "stop A stop!"
    def pause(self):
        raise Exception("Not Implemented")

class B(A):
    def go(self):
        super(B, self).go()
        print "go B go!"

class C(A):
    def go(self):
        super(C, self).go()
        print "go C go!"
    def stop(self):
        super(C, self).stop()
        print "stop C stop!"

class D(B,C):
    def go(self):
        super(D, self).go()
        print "go D go!"
    def stop(self):
        super(D, self).stop()
        print "stop D stop!"
    def pause(self):
        print "wait D wait!"

多重繼承方法或屬性調用順序(MRO)