文章目錄
- 一、前言
- 二、什么是super
- 三、super的常用使用場景
一、前言
最近有粉絲向我咨詢super相關的問題,說網上搜索到的教程不夠通俗易懂,看了之后還是不太理解,所以在這里基于我自己的理解來講解一下super,
二、什么是super
1.super也是一個類,是的,他不是一個方法也不是一個內置的關鍵字,
class A:
pass
print(type(super(A)))
輸出結果
<class 'super'>
直接通過查看super的原始碼也可以看出它是一個類

另外,網上很多文章講解super就是用來呼叫父類方法的,這也是一個錯誤的觀點!
假如我們有下面這樣一個例子:
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__()
class C(A):
def __init__(self):
print("C")
super().__init__()
class D(B, C):
def __init__(self):
print("D")
super().__init__()
D()
如果按照“super就是用來呼叫父類的方法的”這樣的理解來看,那上述代碼的執行的程序應該為:
print("D")—【呼叫super會先后執行B和C】—先執行B:print("B")—【呼叫super執行A】—print("A")—【呼叫super會先后執行B和C】—后執行C:print("C")—【呼叫super執行A】—print("A")
執行結果理論應該為:D B A C A
但實際情況卻不是這樣的!
實際執行結果
D
B
C
A
所以說“super就是用來呼叫父類的方法的”這個說法是錯誤的!
實際上super的呼叫是遵循Python的【MRO(方法決議順序)】來執行的,在Python3中,MRO是基于C3演算法來實作的,
關于MRO和C3演算法的講解可以參考這篇文章http://kaiyuan.me/2016/04/27/C3_linearization/
三、super的常用使用場景
1.假如我們繼承的多個父類有同名的方法,可以使用super來指定使用哪個父類的方法
class A:
def test(self):
print('A')
class B:
def test(self):
print('B')
class C(A, B):
def __init__(self):
super().test() # 呼叫A類中的test方法
super(C, self).test() # 呼叫A類中的test方法
super(A, self).test() # 呼叫B類中的test方法
C()
輸出結果
A
A
B
2.當我們在子類中使用父類的一個方法并且想對其做一定擴展又不想完全重寫,那么使用super()就可以實作方法的增量修改:
舉一個例子,如果我們想把list中的append的方法改為中文添加應該怎么做呢?
并且python中list呼叫append方法是沒有回傳值的,我們想在添加元素操作成功后加一個回傳值回傳成功又該如何操作呢?
首先看通過呼叫原來的list的執行結果
a=list()
res=a.append(1)
print(res)
輸出結果
None
可以看到呼叫append方法后回傳的值為None
現在我們通過super進行重寫,讓其具有回傳值并可以直接通過中文來呼叫append:
class 串列(list):
def 添加(self, *args, **kwargs):
super().append(*args, **kwargs)
return "添加成功"
x = 串列()
res = x.添加(1)
print(res)
print(x)
輸出結果
添加成功
[1]
super實際上還是很常用的,比如在restfremework中,需要重寫其回應結果的Response資訊的時候,除了通過django的中間件實作,也可以使用super重寫其dispatch來實作,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/300033.html
標籤:其他
上一篇:更高效地刷OJ——Java中常用的排序方法,Array.sort(),Arrays.parallelSort(), Collections.sort()
