天天看點

python的super方法_Python的Super方法

原标題:Python的Super方法

我們最常見的,可以說幾乎唯一能見到的使用super的形式是:

python的super方法_Python的Super方法

其中,最常見的method()是init()

以前做過Java,剛剛接觸Python的繼承,的确感覺有點奇怪,有時候還能搞混。。。當然這還是因為Java是單繼承,隻能用接口實作類似多繼承的方式,而Python就直接支援多繼承。

當我第一次見到這個super()的時候,我想說,這是啥啊?為什麼Python的super看起來這麼奇怪呢?

super直接指向父類的執行個體不就得了麼?為什麼非得搞兩個參數?

而且第一個參數還是自己的類名,而不是父類的類名!

既然是自己的類名你還費勁寫一遍幹嘛,幹脆省略不得了?

第二個參數為啥是self?既然是self你省略不得了?

還有,super()傳回的是個啥玩意啊,為什麼可以.method() ? 難道他傳回了一個BaseClass的instance麼?

今天就來解答這一連串的問題。

1)super直接指向父類的執行個體不就得了麼?

首先是不能指向,因為子類執行個體裡面根本就沒有一個父類執行個體,這跟java是不同的。詳細看這裡。

其次是即便像我們想象的,子類執行個體裡有一個叫super的指針,指向父類的執行個體(這個父類執行個體在子類執行個體生成的時候自動生成了,是子類執行個體的一個‘成員’)。

但是由于多繼承的存在,還是會有問題。這也是跟java不同,java不支援多繼承,java用接口的方式實作多繼承。

舉個例子:

當隻存在單繼承的時候,一切很美好,就像java一樣:

你隻需要在重寫方法的時候,用super去調用父類的方法,然後再做自己的事就可以了。

但是在多繼承的情況下,一切都不美好了:

當藝人展示自己能力的時候,他說,父親啊,你先展示自己的能力,然後我來!

但是父親是誰? 他有兩個父親! 總不能寫兩遍 super.展示自己 吧?

那麼我們自然想到,給super搞一個參數不得了,指出super的是哪個父類。

比如 super(歌手).展示自己(),super(演員).展示自己(),好像一切又可以美好了:

先不說這種寫法多麼的醜陋,重複了那麼多無意義的、類似的行,單說這種方法根本就行不通。

我們看看如果某個藝人的執行個體調用了.展示能力() ,将會輸出什麼:

python的super方法_Python的Super方法

有必要告訴大家兩遍你是個人類麼?這要是一個又身兼了主持人的藝人,豈不是得大聲宣布三次自己是個人類??

這顯然是不好的。

而且,這隻是其一,假設多說了幾遍自己是人類你也能忍,那麼還有一種情況,更糟。

你比如說,藝人類沒有重寫 展現自己() 這個方法,當你用藝人的執行個體去調用 展現自己()的時候,将會發生啥?

不重寫的方法自動調用父類的,但是有兩個父類呀!調用哪個的呢?任意調用一個(比如按從左到右的順序)?

那麼展現不出他另一個父類的特點呀!比如調用歌手類的,那隻能展現出這個藝人既是個歌手,又是個人類,根本展現不出他是個演員!

兩個都調用?那萬一其中一個父類沒有這個方法呢?而且先調用哪個後調用哪個?按照左右順序麼?

總之這樣很亂,編譯器表示壓力很大。

是以,python的super()用了兩個參數。

先寫在這裡:

super(SubClass, self).method() 的意思是,根據self去找SubClass的‘父親’,然後調用這個‘父親’的method()

最最重點的地方來了:對于一個類來說,它的‘父類’到底是誰,取決于站在誰的角度去看。

python的super方法_Python的Super方法

‘父親’之是以加了引号,是因為‘父親’并不一定是上下級的繼承關系,很可能隻是兄弟。比如上圖中歌手的‘父親’是‘演員’,但實際上他們是兄弟關系。

是以以後用‘下一個類’來代替這個帶引号的‘父親’。

總之,站在不同的執行個體的角度,看到的‘下一個類’是不同的。

這就是super()第二個參數————self 的意義。

如果是一個歌手執行個體調用的,那麼self=歌手執行個體,super()将站在一個歌手的角度,去找歌手類的‘下一個類’,則會找到人類;

如果是一個藝人執行個體調用的,那麼self=藝人執行個體,super()将站在一個藝人的角度,去找歌手類的‘下一個類’,則會找到演員。

代碼如下:

python的super方法_Python的Super方法

運作結果:

python的super方法_Python的Super方法

這裡需要注意:當一個類從多個類繼承的時候,按照從左到右的順序。

也就是說,站在藝人的角度,首先看到藝人類的‘下一個類’是歌手類,然後歌手類的‘下一個類’是演員類。

這是因為歌手寫在了左邊:Artist(Singer, Actor)

看一下上面代碼的執行過程吧:

由于 super() 絕大多數時候,都在咱們開篇說的這種情況下使用,即在類的定義語句塊内部寫:super(本類名,self)

是以 python3 做了個簡化,如果你在類定義的語句塊内寫一個不帶參數的super(),則相當于寫了 super(本類名,self)

因為 super() 不光可以用在類的定義内部,是以,這種友善僅在類定義體内部有效。傳回搜狐,檢視更多

責任編輯: