深入理解Python中的super()方法
前言
python的類(lèi)分別有新式類(lèi)和經(jīng)典類(lèi),都支持多繼承。在類(lèi)的繼承中,如果你想要重寫(xiě)父類(lèi)的方法而不是覆蓋的父類(lèi)方法,這個(gè)時(shí)候我們可以使用super()方法來(lái)實(shí)現(xiàn)
python語(yǔ)言與C++有相似的類(lèi)繼承,在類(lèi)定義時(shí),python中會(huì)自定義第一個(gè)self,類(lèi)似C++中this指針,指向?qū)ο笞陨怼?br />
python簡(jiǎn)單的類(lèi)舉例:
>>> class hello(object): ... def print_c(): ... print"hello world!" >>> hello().print_c() hello world!
當(dāng)然在實(shí)際中不可避免的需要類(lèi)的繼承,子類(lèi)繼承父類(lèi),正常如下:
>>> class child(hello): ... def print_c(self): ... hello().print_c() ... >>> child().print_c() hello world!
在python中還提供了super()機(jī)制,例子如下:
>>> class hello(object): ... def print_c(self): ... print"hello world!" ... >>> class child(hello): ... def print_c(self): ... super(child,self).print_c() ... >>> child().print_c() hello world!
注意
Python2.2以前的版本:經(jīng)典類(lèi)(classic class)時(shí)代
經(jīng)典類(lèi)是一種沒(méi)有繼承的類(lèi),實(shí)例類(lèi)型都是type類(lèi)型,如果經(jīng)典類(lèi)被作為父類(lèi),子類(lèi)調(diào)用父類(lèi)的構(gòu)造函數(shù)時(shí)會(huì)返回這樣的錯(cuò)誤 '''TypeError: must be type, not classobj'''
這時(shí)MRO的方法為DFS(深度優(yōu)先搜索(子節(jié)點(diǎn)順序:從左到右))。所以本文中使用的是新式類(lèi),而新式類(lèi)的搜索算法是C3算法
class C(object): def minus(self,x): return x/2 class D(C): def minus(self,x): super(D, self).minus() print 'hello'
上面的代碼中C是父類(lèi),D是子類(lèi),我們?cè)贒類(lèi)重新定義了minus方法,就是在C類(lèi)的功能基礎(chǔ)基礎(chǔ)上新添print 'hello'功能。super在這里的作用就是在子類(lèi)中調(diào)用父類(lèi)的方法,這個(gè)也是在單繼承常見(jiàn)調(diào)用super()的用法。那么問(wèn)題來(lái)了
class A(object): def __init__(self): self.n = 10 def minus(self, m): self.n -= m class B(A): def __init__(self): self.n = 7 def minus(self, m): super(B,self).minus(m) self.n -= 2 b=B() b.minus(2) print b.n
那么上面的代碼中b.n的輸出是什么呢?為什么結(jié)果是2呢,而不是5呢?super(B,self).minus(m)明明是調(diào)用了父類(lèi)的minus方法,可是輸出結(jié)果就是2,是你要明白現(xiàn)在B的實(shí)例,而不是A的實(shí)例,那么傳遞的self.n的數(shù)值是7,而不是10.
那么對(duì)于多繼承的時(shí)候,super又是怎樣工作的呢?來(lái),現(xiàn)在創(chuàng)建一個(gè)繼承A的C類(lèi),然后再創(chuàng)建一個(gè)繼承B,C的D類(lèi),看看怎樣調(diào)用super是重寫(xiě)方法。
class C(A): def __init__(self): self.n = 12 def minus(self, m): super(C,self).minus(m) self.n -= 5 class D(B, C): def __init__(self): self.n = 15 def minus(self, m): super(D,self).minus(m) self.n -= 2 d=D() d.minus(2) print d.n
如上的代碼輸出的結(jié)果是什么呢?別心急,先看看它是怎樣運(yùn)行的。上面提及到新式類(lèi)尋找子節(jié)點(diǎn)時(shí)候使用的是C3算法。那么它是怎么找呢。D->B->C->A->object。怎樣才能驗(yàn)證這個(gè)順序是對(duì)的呢。
D.__mro__ (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
Mro是什么呢?對(duì)于你定義的每一個(gè)類(lèi),Python 會(huì)計(jì)算出一個(gè)方法解析順序(Method Resolution Order, MRO)列表,它代表了類(lèi)繼承的順序。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Python中的defaultdict模塊和namedtuple模塊的簡(jiǎn)單入門(mén)指南
這篇文章主要介紹了Python中的defaultdict模塊和namedtuple模塊的簡(jiǎn)單入門(mén)指南,efaultdict繼承自dict、namedtuple繼承自tuple,是Python中內(nèi)置的數(shù)據(jù)類(lèi)型,需要的朋友可以參考下2015-04-04python實(shí)現(xiàn)名片管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)名片管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11