久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Python類的繼承super相關(guān)原理解析

瀏覽:96日期:2022-07-07 14:31:02

看了網(wǎng)上許多關(guān)于super、mro、C3的介紹感覺(jué)沒(méi)有一份很容易初學(xué)者理解的文檔,直接看C3算法的話,比較難理解,也沒(méi)必要,如果掌握一套規(guī)律的話,會(huì)輕松許多。我將網(wǎng)上這些博主的文章進(jìn)行一個(gè)梳理總結(jié),最后形成一套實(shí)用的關(guān)于super、mro、C3的理解介紹。

1、super

super()是一種將子類與父類聯(lián)系起來(lái)的一種方法,子類通過(guò)繼承父類,可以使用父類的方法和屬性,也可以自己定義屬于自己的方法和屬性。super方法主要用在多繼承中,在單繼承時(shí)直接調(diào)用父類方法即可

下面這個(gè)是SGD源碼的一部分,根據(jù)這份源碼,

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點(diǎn)需要補(bǔ)充說(shuō)明:

1、super聯(lián)系父類的時(shí)候,需要調(diào)用父類的方法,包括所帶的形參寫(xiě)完整,子類不夠的形參需要額外加上

2、super聯(lián)系父類的時(shí)候,不只是可以調(diào)用__init__,而且還可以調(diào)用父類其他的方法

3、python3可以寫(xiě)成super().__init__()這種寫(xiě)法了。

4、類都默認(rèn)繼承object類

另外,在super的使用過(guò)程中,還需要注意初始化對(duì)繼承的影響:

1、子類繼承父類,但不執(zhí)行__init__方法,那么會(huì)自動(dòng)繼承父類屬性。

2、子類繼承父類,執(zhí)行了__init__方法,且不調(diào)用super初始化父類構(gòu)造函數(shù),那么子類不會(huì)自動(dòng)繼承父類屬性。

3、子類繼承父類,執(zhí)行了__init__方法,且調(diào)用了super初始化了父類的構(gòu)造函數(shù),那么子類會(huì)繼承父類屬性。

2、mro

Python的MRO,方法解析順序,即在調(diào)用方法時(shí),會(huì)對(duì)當(dāng)前類以及所有的基類進(jìn)行一個(gè)搜索,以確定該方法之所在,而這個(gè)搜索的順序就是MRO。然后python會(huì)按照這個(gè)順序去執(zhí)行類之間的調(diào)用問(wèn)題。

直接上例子

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__)

輸出如下:

Python類的繼承super相關(guān)原理解析

(<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’>)

那么這個(gè)程序是按怎么個(gè)順序依次去執(zhí)行那些方法呢,就是按照MRO中的順序。

Python類的繼承super相關(guān)原理解析

那么這個(gè)順序如何自己手寫(xiě)出來(lái)呢?這就是C3算法,用于計(jì)算出MRO,得出執(zhí)行順序

3、c3算法

但是我在這里想告訴大家如何根據(jù)C3算法找出規(guī)律,從而自己寫(xiě)出順序

還是上手例子,根據(jù)上面這個(gè)圖,我們可以列出下面這個(gè)表,這個(gè)表示網(wǎng)上一個(gè)博主做的,可以說(shuō)做出這張表就是做出了答案,那這張表“實(shí)際取出的類”怎么推出來(lái)的呢?我拿過(guò)來(lái)提煉出一些比較直接的規(guī)律

Python類的繼承super相關(guān)原理解析

規(guī)律1:預(yù)查找父類按左邊優(yōu)先原則,比如第一行,當(dāng)前類D的預(yù)查找父類選最左邊的C1,而不是C2、C3。

規(guī)律2:當(dāng)“預(yù)查找父類是否還有其他子類?同時(shí)又是最底層查找類的父類或父父類、父父父...類”沒(méi)有的時(shí)候,直接選取預(yù)查找父類作為答案。當(dāng)這項(xiàng)有類的時(shí)候,若“最底層的未查找父類”還有,則優(yōu)先選它,若沒(méi)有了,則選取這項(xiàng)類作為答案。

規(guī)律3:當(dāng)預(yù)查找父類是object,只要最底層的未查找父類還有,就選這個(gè)最底層的未查找父類。若沒(méi)有,則“預(yù)查找父類是否還有其他子類?同時(shí)又是最底層查找類的父類或父父類、父父父...類”有類的時(shí)候,就選這個(gè)類,沒(méi)有的話,答案就是object

另外,

如何去畫(huà)圖:

1、子類永遠(yuǎn)畫(huà)在父類的下面,并用有向箭頭指向父類

2、遇到多繼承則按代碼中繼承列表的順序從左往右寫(xiě)。如果有多個(gè)子類繼承了同一個(gè)父類,那么這個(gè)父類則放在它能夠出現(xiàn)的所有位置中最左的位置。需遵循圖里面的廣度優(yōu)先原則進(jìn)行遍歷(在廣度優(yōu)先原則的前提下又優(yōu)先遍歷左邊的):

練習(xí):

下面這個(gè)是網(wǎng)上的一份代碼,看懂上面的規(guī)律以及如何畫(huà)有向圖之后,就可以順利得出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__()

首先,畫(huà)圖

Python類的繼承super相關(guān)原理解析

然后列表

當(dāng)前類最底層未查找的父類預(yù)查找的父類預(yù)查找父類是否為object預(yù)查找父類是否有其他子類,同時(shí)又是最底層查找類的父類、父父類實(shí)際取出的類GE、FEnonoEEFBnonoBBFAno有,CFFnoCnonoCCnoAno有,DDDnoAnonoAAnoobjectyesnoobject

答案:

mro:GEBFC

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品午夜视频 | 99精品欧美一区二区三区 | 欧美一极片 | 亚洲欧美在线视频 | 成人亚洲精品 | 久久久久久影院 | 亚洲欧美成人网 | 欧美激情精品久久久久久 | 欧美激情精品久久久久久免费 | 国产一区999| 一区二区三区影视 | 中文字幕一区二区三区乱码图片 | 99视频网站 | 欧美日韩中文字幕 | 野狼在线社区2017入口 | 日韩精品一二三 | 操人网| 国产一区二区视频在线观看 | 欧美国产日韩一区二区 | 精品久久久久久久久久久久久久 | 国产一在线 | 国产在线播 | 午夜精品视频 | 久久久国产精品入口麻豆 | 日韩精品一91爱爱 | 一区视频在线 | 久艹精品| 人人干人人干人人 | 欧美激情综合色综合啪啪五月 | 免费观看成人毛片 | 在线a视频 | 成人av免费观看 | 欧美另类一区二区 | 色爽女人免费 | 五月天婷婷综合 | 久在线视频 | 玖玖成人 | 91精品国产综合久久精品 | 在线观看亚洲 | 久久日韩| 毛片网站在线观看 |