super的實例及實現原理

super實例

class A():
    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!")
class E(B,C):
    pass
a = A()
b = B()
c = C()
d = D()
e = E()
# 說明下列代碼的輸出結果
a.go()
print('--------')
b.go()
print('--------')
c.go()
print('--------')
d.go()
print('--------')
e.go()
print('--------')
a.stop()
print('--------')
b.stop()
print('--------')
c.stop()
print('--------')
d.stop()
print('--------')
e.stop()
print(D.mro())
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()

答案

a.go()# go A go!
b.go()# go A go!# go B go!
c.go()# go A go!# go C go!
d.go()# go A go!# go C go!# go B go!# go D go!
e.go()# go A go!# go C go!# go B go!
a.stop()# stop A stop!
b.stop()# stop A stop!
c.stop()# stop A stop!# stop C stop!
d.stop()# stop A stop!# stop C stop!# stop D stop!
e.stop()# stop A stop!
a.pause()# ... Exception: Not Implemented
b.pause()# ... Exception: Not Implemented
c.pause()# ... Exception: Not Implemented
d.pause()# wait D wait!
e.pause()# ...Exception: Not Implemented

  

super原理

super的工做原理以下:python

def super(cls, inst):
    mro = inst.__class__.mro()
    return mro[mro.index(cls) + 1]

cls表明類,inst表明實例,能夠看出上面的代碼作了兩件事:blog

  • 獲取inst的MRO列表。
  • 查找cls在MRO的index,並返回它的下一個類,即mro[index + 1]

當你使用super(cls, inst)時,python會在inst的MRO列表上搜索下cls的下一個類。it

如今再回答前面的例子:io

super(C, self).__init__()

這裏的self是C的實例,self.class.mro()的結果是;class

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]

能夠看到C的下一個類是A,因而,跳到了A的init,這時會打印enter A,而且執行下面一行代碼:原理

super(A, self).__init__()

注意這裏的self也是當前C的實例,MRO列表和以前是同樣的。搜索A在MRO中下的一個類,發現是B,因而又跳到了B的init,這時會打印enter B,而不是enter Base。object

上面整個過程仍是比較清晰的,關鍵在於理解super的工做方式,而不是想固然的理解爲super調用父類的方法。搜索

總結:方法

  • super和父類沒有實質性的關聯。
  • super(cls, inst)得到的是cls在inst的MRO列表中下一個類。
相關文章
相關標籤/搜索