看了網上許多關於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就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...