深入理解Python 關(guān)于supper 的 用法和原理
一、前言
Python 面向?qū)ο笾杏欣^承這個(gè)概念,初學(xué)時(shí)感覺(jué)很牛逼,里面也有個(gè)super類(lèi),經(jīng)常見(jiàn)到,最近做一些題才算是理解了。特地記錄分享給后來(lái)研究的小伙伴,畢竟現(xiàn)在小學(xué)生都開(kāi)始學(xué)了(滑稽臉)
二、代碼
直接上干貨,能把下面一個(gè)問(wèn)題全答對(duì),后面就不用看了。
class A():
def go(self):
print ("go A go!")
def stop(self):
print ("stop A stop!")
def pause(self):
raise Exception("Not Implemented")
class B(A):
def go(self):
super(B, self).go()
print ("go B go!")
class C(A):
def go(self):
super(C, self).go()
print ("go C go!")
def stop(self):
super(C, self).stop()
print ("stop C stop!")
class D(B,C):
def go(self):
super(D, self).go()
print ("go D go!")
def stop(self):
super(D, self).stop()
print ("stop D stop!")
def pause(self):
print ("wait D wait!")
class E(B,C):
pass
a = A()
b = B()
c = C()
d = D()
e = E()
# 說(shuō)明下列代碼的輸出結(jié)果
a.go()
print('--------')
b.go()
print('--------')
c.go()
print('--------')
d.go()
print('--------')
e.go()
print('--------')
a.stop()
print('--------')
b.stop()
print('--------')
c.stop()
print('--------')
d.stop()
print('--------')
e.stop()
print(D.mro())
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
當(dāng)然,直接運(yùn)行就有答案了,還是要仔細(xì)想一下,反正看到我第一次跑出的結(jié)果的時(shí)候,我都不敢相信自己的眼睛。
step1:
幾個(gè)概念:
繼承的功能:父類(lèi)的代碼重用
多態(tài)的功能:同一方法對(duì)不同類(lèi)型的對(duì)象會(huì)有相應(yīng)的結(jié)果
開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉
super類(lèi)功能:新式類(lèi)實(shí)現(xiàn)廣度優(yōu)先的不重復(fù)的調(diào)用父類(lèi),解決了鉆石繼承(多繼承)的難題
step2:
super實(shí)現(xiàn)原理:通過(guò)c3算法,生成mro(method resolution order)列表,根據(jù)列表中元素順序查詢調(diào)用
新式類(lèi)調(diào)用順序?yàn)閺V度優(yōu)先,舊式類(lèi)為深度優(yōu)先
step3:
個(gè)人理解:
1.調(diào)用了父類(lèi)的方法,出入的是子類(lèi)的實(shí)例對(duì)象
2.新式類(lèi)子類(lèi)(A,B),A就在B之前
3.super類(lèi)似于嵌套的一種設(shè)計(jì),當(dāng)代碼執(zhí)行到super實(shí)例化后,先去找同級(jí)父類(lèi),若沒(méi)有其余父類(lèi),再執(zhí)行自身父類(lèi),再往下走,
簡(jiǎn)潔點(diǎn)的三個(gè)原則就是:
子類(lèi)在父類(lèi)前,所有類(lèi)不重復(fù)調(diào)用,從左到右
理解了以上的說(shuō)法,題目就沒(méi)問(wèn)題了。
也不用跑了,答案如下:
a.go()# go A go! b.go()# go A go!# go B go! c.go()# go A go!# go C go! d.go()# go A go!# go C go!# go B go!# go D go! e.go()# go A go!# go C go!# go B go! a.stop()# stop A stop! b.stop()# stop A stop! c.stop()# stop A stop!# stop C stop! d.stop()# stop A stop!# stop C stop!# stop D stop! e.stop()# stop A stop! a.pause()# ... Exception: Not Implemented b.pause()# ... Exception: Not Implemented c.pause()# ... Exception: Not Implemented d.pause()# wait D wait! e.pause()# ...Exception: Not Implemented
看了答案,其實(shí)還有一點(diǎn),父類(lèi)拋異常的情況,如果子類(lèi)有不拋異常的方法,異常就不拋出了,這個(gè)設(shè)計(jì)也會(huì)很有用。
這里就中間一個(gè)A,C,B,D的和網(wǎng)上常見(jiàn)的不太一樣,促使我仔細(xì)研究了一下,其實(shí)就是個(gè)人理解第三條。
補(bǔ)充:
Python2 和Python3在這個(gè)問(wèn)題上的差別
Python2 沒(méi)有默認(rèn)繼承object
Python3 默認(rèn)全部繼承object類(lèi),都是新式類(lèi)
Python2super調(diào)用 super(開(kāi)始類(lèi)名,self).函數(shù)名()
Python3 super().函數(shù)名()
關(guān)于調(diào)用父類(lèi)函數(shù)傳入子類(lèi)實(shí)例的栗子舉一個(gè):
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
print('newb')
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
print('newc')
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)
self.n += 5
d = D()
d.add(2)
print(d.n)
總結(jié)
以上所述是小編給大家介紹的Python 關(guān)于supper 的 用法和原理,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
python多線程實(shí)現(xiàn)同時(shí)執(zhí)行兩個(gè)while循環(huán)的操作
這篇文章主要介紹了python多線程實(shí)現(xiàn)同時(shí)執(zhí)行兩個(gè)while循環(huán)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05
Python實(shí)現(xiàn)常見(jiàn)的回文字符串算法
這篇文章主要介紹了Python實(shí)現(xiàn)常見(jiàn)的回文字符串算法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11
如何使用Python做個(gè)自定義動(dòng)態(tài)壁紙
這篇文章主要介紹了如何使用Python做個(gè)自定義動(dòng)態(tài)壁紙的相關(guān)資料,需要的朋友可以參考下方法2021-08-08
使用Python分析文本數(shù)據(jù)的詞頻并詞云圖可視化
這篇文章主要給大家介紹了關(guān)于如何使用Python分析文本數(shù)據(jù)的詞頻并詞云圖可視化,文章中有詳細(xì)的圖文介紹和代碼示例,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-09-09
Python+Django在windows下的開(kāi)發(fā)環(huán)境配置圖解
Python+Django在windows下的開(kāi)發(fā)環(huán)境配置圖解教程,需要的朋友可以參考下。2009-11-11
pytorch基礎(chǔ)之損失函數(shù)與反向傳播詳解
損失函數(shù)(Loss?Function)用于衡量神經(jīng)網(wǎng)絡(luò)輸出與目標(biāo)值之間的誤差,指導(dǎo)網(wǎng)絡(luò)通過(guò)反向傳播優(yōu)化參數(shù),常見(jiàn)的損失函數(shù)包括均方誤差和交叉熵誤差,在訓(xùn)練過(guò)程中,通過(guò)不斷最小化損失函數(shù)值來(lái)調(diào)整網(wǎng)絡(luò)權(quán)重,以期達(dá)到輸出接近目標(biāo)值的效果2024-09-09
Python原始字符串(raw strings)用法實(shí)例
這篇文章主要介紹了Python原始字符串(raw strings)用法實(shí)例,在使用Python進(jìn)行字符串處理的過(guò)程中非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10
Python網(wǎng)絡(luò)爬蟲(chóng)之爬取微博熱搜
這篇文章主要介紹了Python網(wǎng)絡(luò)爬蟲(chóng)之爬取微博熱搜的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
Django中更改默認(rèn)數(shù)據(jù)庫(kù)為mysql的方法示例
這篇文章主要介紹了Django中更改默認(rèn)數(shù)據(jù)庫(kù)為mysql的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Python實(shí)現(xiàn)圖像去噪方式(中值去噪和均值去噪)
今天小編就為大家分享一篇Python實(shí)現(xiàn)圖像去噪方式(中值去噪和均值去噪),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12

