在Python類的方法(method)中,要調用父類的某個方法,在Python 2.2以前,通常的寫法如代碼段1:
class A: def __init__(self): print "enter A" print "leave A" class B(A): def __init__(self): print "enter B" A.__init__(self)
print "leave B" >>> b = B() enter B enter A leave A leave B
即,使用非綁定的類方法(用類名來引用的方法),並在參數列表中,引入待綁定的對象(self),從而達到調用父類的目的。
這樣做的缺點是,當一個子類的父類發生變化時(如類B的父類由A變為C時),必須遍歷整個類定義,把所有的通過非綁定的方法的類名全部替換過來,例如代碼段2:
class B(C): def __init__(self): print "enter B" C.__init__(self) print "leave B"
如果代碼簡單,這樣的改動或許還可以接受。但如果代碼量龐大,這樣的修改可能是災難性的。
因此,自Python 2.2開始,Python添加了一個關鍵字super,來解決這個問題。下面是Python3.5的官方文檔說明:https://docs.python.org/3.5/library/functions.html?highlight=super#super
二維碼直達
super([type[, object-or-type]])
調用父類或兄弟類的方法返回給代理對象。這對訪問在類中被覆蓋的父類繼承方法很有用。
super有兩種典型的用例。在具有單一繼承的類層次結構中,super可以用於引用父類,而不用明確地命名它們,從而使代碼更易於維護。這種用法與其他程式語言中的調用父類用法非常類似。
典型的父類調用如下所示:
class C(B): def method(self, arg): super().method(arg) # This does the same thing as: # super(C, self).method(arg)
從說明來看,可以把類B改寫如代碼段3:
class A(object): def __init__(self): print "enter A" print "leave A"
class B(C): def __init__(self): print "enter B" super(B, self).__init__()
print "leave B"
嘗試執行上面同樣的代碼,結果一致,但修改的代碼只有一處,把代碼的維護量降到最低,是一個不錯的用法。因此在我們的開發過程中,super關鍵字被大量使用,而且一直表現良好。
在我們的印象中,對於super(B, self).init()是這樣理解的:super(B,self)首先找到B的父類(就是類A),然後把類B的對象self轉換為類A的對象(通過某種方式,一直沒有考究是什麼方式,慚愧),然後「被轉換」的類A對象調用自己的init函數。考慮到super中只有指明子類的機制,因此,在多繼承的類定義中,通常我們保留使用類似代碼段1的方法。