教你學會使用Python學習之類的繼承super!

2022-07-15 01:18:11 字數 4021 閱讀 9786

看了網上許多關於super、mro、c3的介紹感覺沒有乙份很容易初學者理解的文件,直接看c3演算法的話,比較難理解,也沒必要,如果掌握一套規律的話,會輕鬆許多。我將網上這些博主的文章進行乙個梳理總結,最後形成一套實用的關於super、mro、c3的理解介紹。

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初始化了父類的建構函式,那麼子類會繼承父類屬性。

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

輸出如下:

(, , , , , , , , , , )

那麼這個程式是按怎麼個順序依次去執行那些方法呢,就是按照mro中的順序。

那麼這個順序如何自己手寫出來呢?這就是c3演算法,用於計算出mro,得出執行順序

這個是網上**一篇博主對於c3演算法的介紹,有興趣鑽研的同學可以進去看看

但是我在這裡想告訴大家如何根據c3演算法找出規律,從而自己寫出順序

還是上手例子,根據上面這個圖,我們可以列出下面這個表,這個表示網上乙個博主做的,可以說做出這張表就是做出了答案,那這張表「實際取出的類」怎麼推出來的呢?我拿過來提煉出一些比較直接的規律

另外,如何去畫圖:

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學習4 學會使用函式input

1.1 函式input的工作原理 message input tell me something,and i will repeat it back to you print message 函式input 接受乙個引數 即要向使用者顯示的提示或說明,讓使用者知道該如何做。在這個示例中,python...

python筆記 學會使用Fiddler

fiddler是乙個常見的抓包分析軟體,同時我們可以利用它詳細地對http請求進行分析,並模擬對應的http請求.為什麼使用fiddler軟體?網路爬蟲是自動爬取網頁的程式,在爬取的過程中必然涉及客戶端和服務端的通訊,自然也需要傳送一些http請求,並接受伺服器返回的結果.在一些稍複雜的網路請求紅,...

學會使用SafeArray

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...