您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Python類繼承super的原因,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
1、super
super()是一種將子類與父類聯系起來的一種方法,子類通過繼承父類,可以使用父類的方法和屬性,也可以自己定義屬于自己的方法和屬性。super方法主要用在多繼承中,在單繼承時直接調用父類方法即可
下面這個是SGD源碼的一部分,根據這份源碼,
class SGD(Optimizer): def __init__(self, params, lr=required, momentum=0, dampening=0, weight_decay=0, nesterov=False): defaults = dict(lr=lr, momentum=momentum, dampening=dampening, weight_decay=weight_decay, nesterov=nesterov) if nesterov and (momentum <= 0 or dampening != 0): raise ValueError("Nesterov momentum requires a momentum and zero dampening") super(SGD, self).__init__(params, defaults) def __setstate__(self, state): super(SGD, self).__setstate__(state) for group in self.param_groups: group.setdefault('nesterov', False)
這是SGD類中的代碼
有2點需要補充說明:
1、super聯系父類的時候,需要調用父類的方法,包括所帶的形參寫完整,子類不夠的形參需要額外加上
2、super聯系父類的時候,不只是可以調用__init__,而且還可以調用父類其他的方法
3、python3可以寫成super().__init__()這種寫法了。
4、類都默認繼承object類
另外,在super的使用過程中,還需要注意初始化對繼承的影響:
1、子類繼承父類,但不執行__init__方法,那么會自動繼承父類屬性。
2、子類繼承父類,執行了__init__方法,且不調用super初始化父類構造函數,那么子類不會自動繼承父類屬性。
3、子類繼承父類,執行了__init__方法,且調用了super初始化了父類的構造函數,那么子類會繼承父類屬性。
2、mro
Python的MRO,方法解析順序,即在調用方法時,會對當前類以及所有的基類進行一個搜索,以確定該方法之所在,而這個搜索的順序就是MRO。然后python會按照這個順序去執行類之間的調用問題。
直接上例子
class A1(): def __init__(self): print('A1') super().__init__() class A2(): def __init__(self): print('A2') super().__init__() class A3(): def __init__(self): print('A3') super().__init__() class B1(A1, A2): def __init__(self): print('B1') super().__init__() class B2(A2): def __init__(self): print('B2') super().__init__() class B3(A2, A3): def __init__(self): print('B3') super().__init__() class C1(B1): def __init__(self): print('C1') super().__init__() class C2(B1, B2): def __init__(self): print('C2') super().__init__() class C3(B2, B3): def __init__(self): print('C3') super().__init__() class D(C1, C2, C3): def __init__(self): print('D') super().__init__() d = D() print(D.__mro__)
輸出如下:
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.B1'>, <class '__main__.A1'>, <class '__main__.C3'>, <class '__main__.B2'>, <class '__main__.B3'>, <class '__main__.A2'>, <class '__main__.A3'>, <class 'object'>)
那么這個程序是按怎么個順序依次去執行那些方法呢,就是按照MRO中的順序。
那么這個順序如何自己手寫出來呢?這就是C3算法,用于計算出MRO,得出執行順序
3、c3算法
但是我在這里想告訴大家如何根據C3算法找出規律,從而自己寫出順序
還是上手例子,根據上面這個圖,我們可以列出下面這個表,這個表示網上一個博主做的,可以說做出這張表就是做出了答案,那這張表“實際取出的類”怎么推出來的呢?我拿過來提煉出一些比較直接的規律
規律1:預查找父類按左邊優先原則,比如第一行,當前類D的預查找父類選最左邊的C1,而不是C2、C3。
規律2:當“預查找父類是否還有其他子類?同時又是最底層查找類的父類或父父類、父父父...類”沒有的時候,直接選取預查找父類作為答案。當這項有類的時候,若“最底層的未查找父類”還有,則優先選它,若沒有了,則選取這項類作為答案。
規律3:當預查找父類是object,只要最底層的未查找父類還有,就選這個最底層的未查找父類。若沒有,則“預查找父類是否還有其他子類?同時又是最底層查找類的父類或父父類、父父父...類”有類的時候,就選這個類,沒有的話,答案就是object
另外,
如何去畫圖:
1、子類永遠畫在父類的下面,并用有向箭頭指向父類
2、遇到多繼承則按代碼中繼承列表的順序從左往右寫。如果有多個子類繼承了同一個父類,那么這個父類則放在它能夠出現的所有位置中最左的位置。需遵循圖里面的廣度優先原則進行遍歷(在廣度優先原則的前提下又優先遍歷左邊的):
練習:
下面這個是網上的一份代碼,看懂上面的規律以及如何畫有向圖之后,就可以順利得出MRO的值了
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(A): def __init__(self): print('D') super().__init__() class E(B, C): def __init__(self): print('E') super().__init__() class F(C, D): def __init__(self): print('F') super().__init__() class G(E, F): def __init__(self): print('G') super().__init__()
首先,畫圖
然后列表
當前類最底層未查找的父類預查找的父類預查找父類是否為object預查找父類是否有其他子類,同時又是最底層查找類的父類、父父類實際取出的類GE、FEnonoEEFBnonoBBFAno有,CFFnoCnonoCCnoAno有,DDDnoAnonoAAnoobjectyesnoobject
答案:
mro:GEBFC
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家
以上就是Python類繼承super的原因,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。