Python中super關(guān)鍵字用法實(shí)例分析
本文實(shí)例講述了Python中super關(guān)鍵字用法。分享給大家供大家參考。具體分析如下:
在Python類(lèi)的方法(method)中,要調(diào)用父類(lèi)的某個(gè)方法,在Python 2.2以前,通常的寫(xiě)法如代碼段1:
代碼段1:
class A: def __init__(self): print "enter A" print "leave A" class B(A): def __init__(self): print "enter B" A.__init__(self) print "leave B" >>> b = B() enter B enter A leave A leave B
即,使用非綁定的類(lèi)方法(用類(lèi)名來(lái)引用的方法),并在參數(shù)列表中,引入待綁定的對(duì)象(self),從而達(dá)到調(diào)用父類(lèi)的目的。
這樣做的缺點(diǎn)是,當(dāng)一個(gè)子類(lèi)的父類(lèi)發(fā)生變化時(shí)(如類(lèi)B的父類(lèi)由A變?yōu)镃時(shí)),必須遍歷整個(gè)類(lèi)定義,把所有的通過(guò)非綁定的方法的類(lèi)名全部替換過(guò)來(lái),例如代碼段2,
代碼段2:
class B(C): # A --> C def __init__(self): print "enter B" C.__init__(self) # A --> C print "leave B"
如果代碼簡(jiǎn)單,這樣的改動(dòng)或許還可以接受。但如果代碼量龐大,這樣的修改可能是災(zāi)難性的。很容易導(dǎo)致修改錯(cuò)誤的出現(xiàn)。
因此,自Python 2.2開(kāi)始,Python添加了一個(gè)關(guān)鍵字super,來(lái)解決這個(gè)問(wèn)題。下面是Python 2.3的官方文檔說(shuō)明:
super(type[, object-or-type]) Return the superclass of type. If the second argument is omitted the super object returned is unbound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true. super() only works for new-style classes. A typical use for calling a cooperative superclass method is: class C(B): def meth(self, arg): super(C, self).meth(arg) New in version 2.2.
從說(shuō)明來(lái)看,可以把類(lèi)B改寫(xiě)如代碼段3:
代碼段3:
class A(object): # A must be new-style class def __init__(self): print "enter A" print "leave A" class B(C): # A --> C def __init__(self): print "enter B" super(B, self).__init__() print "leave B"
嘗試執(zhí)行上面同樣的代碼,結(jié)果一致,但修改的代碼只有一處,把代碼的維護(hù)量降到最低,是一個(gè)不錯(cuò)的用法。因此在我們的開(kāi)發(fā)過(guò)程中,super關(guān)鍵字被大量使用,而且一直表現(xiàn)良好。
1. super并不是一個(gè)函數(shù),是一個(gè)類(lèi)名,形如super(B, self)事實(shí)上調(diào)用了super類(lèi)的初始化函數(shù),產(chǎn)生了一個(gè)super對(duì)象;
2. super類(lèi)的初始化函數(shù)并沒(méi)有做什么特殊的操作,只是簡(jiǎn)單記錄了類(lèi)類(lèi)型和具體實(shí)例;
3. super(B, self).func的調(diào)用并不是用于調(diào)用當(dāng)前類(lèi)的父類(lèi)的func函數(shù);
4. Python的多繼承類(lèi)是通過(guò)mro的方式來(lái)保證各個(gè)父類(lèi)的函數(shù)被逐一調(diào)用,而且保證每個(gè)父類(lèi)函數(shù)只調(diào)用一次(如果每個(gè)類(lèi)都使用super);
5. 混用super類(lèi)和非綁定的函數(shù)是一個(gè)危險(xiǎn)行為,這可能導(dǎo)致應(yīng)該調(diào)用的父類(lèi)函數(shù)沒(méi)有調(diào)用或者一個(gè)父類(lèi)函數(shù)被調(diào)用多次。
從super關(guān)鍵字的help我們也能看出來(lái)。
Help on class super in module __builtin__:
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
|
| Methods defined here:
.......
從上面也能看出來(lái),super是一個(gè)類(lèi),而且是__builtin__模塊中的。
從上面的描述來(lái)看,super主要是用于調(diào)用父類(lèi)的方法。
那么,在2.2之前的方法也能調(diào)用。為啥非得用super呢?
這是因?yàn)閟uper能夠阻止對(duì)父類(lèi)方法的多次調(diào)用。
super,改變了父類(lèi)搜索順序, 返回的是一個(gè)特殊的父類(lèi)對(duì)象
看例子:
class A: pass class B(A): pass class C(A):pass class D(B, C): pass
這是4個(gè)類(lèi)的基本關(guān)系。
假如不使用super,讓D的對(duì)象調(diào)用他們共有的一個(gè)方法,會(huì)2次調(diào)用A中這個(gè)方法。
希望本文所述對(duì)大家的Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
12個(gè)Python程序員面試必備問(wèn)題與答案(小結(jié))
這篇文章主要介紹了12個(gè)Python程序員面試必備問(wèn)題與答案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-06-06通過(guò)實(shí)例解析Python return運(yùn)行原理
這篇文章主要介紹了通過(guò)實(shí)例解析Python return運(yùn)行原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03聊聊Pytorch torch.cat與torch.stack的區(qū)別
這篇文章主要介紹了Pytorch torch.cat與torch.stack的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05python目標(biāo)檢測(cè)SSD算法預(yù)測(cè)部分源碼詳解
這篇文章主要為大家介紹了python目標(biāo)檢測(cè)SSD算法預(yù)測(cè)部分源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python使用QQ郵箱發(fā)送郵件實(shí)例與QQ郵箱設(shè)置詳解
這篇文章主要介紹了Python發(fā)送QQ郵件實(shí)例與QQ郵箱設(shè)置詳解,需要的朋友可以參考下2020-02-02