關於Python3中的super()函數
我們都知道,在Python3中子類在繼承父類的時候,當子類中的方法與父類中的方法重名時,子類中的方法會覆蓋父類中的方法,
那么,如果我們想實現同時調用父類和子類中的同名方法,就需要使用到super()這個函數,用法為super().函數名()
下面是一個例子:
class A1(): def go(self): print("go A1 go") class A2(): def go(self): print("go A2 go") class A3(): def go(self): print("go A3 go") class C(A3): pass class B(A1,A2): pass class D(B,C): def go(self): print("NMSL") super().go() d1 = D() d1.go() print(D.__mro__)
輸出結果為:
NMSL go A1 go (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A1'>, <class '__main__.A2'>, <class '__main__.C'>, <class '__main__.A3'>, <class 'object'>)
這里的__mro__屬性顯示了當類調用方法時,如果父類和子類中有同名方法情況下的查找順序。
如圖,當我們實例化D類並調用類中的go方法時,go方法中有一條語句調用了父類的go方法,__mro__屬性顯示了如何查找這個方法(當然,自身類中的go方法不算),最后我們知道它調用的是A1類中的go方法,那么有些人會疑惑,為什么它不調用更近的的A3類或者A2類中go方法呢,這就要涉及到super()函數實現順序查找的算法,這個算法即為C3算法。我的另一篇博客中記錄了這個算法的原理。
假如D類中本身就沒有go方法,那么我們再使用super()函數進行調用go方法,它會選擇哪一個父類的呢?
代碼如下:
class A1(): def go(self): print("go A1 go") class A2(): def go(self): print("go A2 go") class A3(): def go(self): print("go A3 go") class C(A3): pass class B(A1,A2): pass class D(B,C): def gogo(self): print("NMSL") super().go() d1 = D() d1.gogo() print(D.__mro__)
運行后輸出結果:
NMSL go A1 go (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A1'>, <class '__main__.A2'>, <class '__main__.C'>, <class '__main__.A3'>, <class 'object'>)
可以看到結果還是這樣。
如果D類中不定義方法,僅僅在類的外部通過實例調用go方法,查找過程也是一樣的。
如圖:
class D(B,C):
pass
d1 = D() d1.go() print(D.__mro__)
結果:
NMSL go A1 go (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A1'>, <class '__main__.A2'>, <class '__main__.C'>, <class '__main__.A3'>, <class 'object'>)
以上就是對於super()函數的個人看法。