溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python中的super函數(shù)怎么用

發(fā)布時(shí)間:2022-10-12 15:04:04 來(lái)源:億速云 閱讀:95 作者:iii 欄目:web開(kāi)發(fā)

這篇文章主要介紹了Python中的super函數(shù)怎么用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Python中的super函數(shù)怎么用文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。

實(shí)戰(zhàn)場(chǎng)景

經(jīng)常有朋友問(wèn),學(xué) Python 面向?qū)ο髸r(shí),翻閱別人代碼,會(huì)發(fā)現(xiàn)一個(gè) super() 函數(shù),那這個(gè)函數(shù)的作用到底是什么?

super() 函數(shù)的用途如下,在子類中調(diào)用父類的方法,多用于類的繼承關(guān)系。

其語(yǔ)法格式如下所示:

super(type[, object-or-type])

參數(shù)說(shuō)明如下:

  • type:類,可選參數(shù)

  • object-or-type:對(duì)象或類,一般為 self,也是可選參數(shù)。

返回值是代理對(duì)象。

可以直接查詢官方幫助手冊(cè):

help(super)

輸出信息如下所示:

Help on class super in module builtins:
class super(object)
 |  super() -> same as super(__class__, <first argument>)
 |  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().meth(arg)
 |  This works for class methods too:
 |  class C(B):
 |      @classmethod
 |      def cmeth(cls, arg):
 |          super().cmeth(arg)

對(duì)輸出結(jié)果進(jìn)行分析之后,可以得到如下結(jié)論:

  • super 類是一個(gè)繼承自 object 的類,super() 函數(shù)就是對(duì)該類的實(shí)例化;

  • 調(diào)用 super() 實(shí)例化之后,返回一個(gè) super 對(duì)象;

  • super() 參數(shù)有四種搭配,具體看上述輸出;

實(shí)戰(zhàn)編碼

單繼承使用

直接看一下單繼承相關(guān)代碼,其中使用類名去調(diào)用父類方法。

class A:
 def funA(self):
 print("執(zhí)行 A ,輸出橡皮擦")
class B(A):
 def funB(self):
 # self 表示 B 類的實(shí)例
 A.funA(self)
 print("執(zhí)行 B ,輸出鉛筆")
b = B()
b.funB()

上述代碼在 B 類中增加了 funB 函數(shù),并且去調(diào)用 A 類中的 funA 函數(shù),此時(shí)輸出的內(nèi)容如下所示:

執(zhí)行 A ,輸出橡皮擦
執(zhí)行 B ,輸出鉛筆

如果將上述代碼修改為 super() 函數(shù)調(diào)用父類方法,可以使用下述代碼:

class A:
 def funA(self):
 print("執(zhí)行 A ,輸出橡皮擦")
class B(A):
 def funB(self):
 # 注意 super() 函數(shù)的用法
 super().funA()
 print("執(zhí)行 B ,輸出鉛筆")
b = B()
b.funB()

上述代碼與之前的運(yùn)行結(jié)果一致,在單繼承的層級(jí)結(jié)構(gòu)中,super 可以直接引用父類,即在子類中不需要使用父類名調(diào)用父類方法,而使用 代理對(duì)象(super 對(duì)象) 去調(diào)用,這樣的好處就是當(dāng)父類名改變或繼承關(guān)系發(fā)生改變時(shí),我們不需要對(duì)調(diào)用進(jìn)行反復(fù)修改。

接下來(lái)看一下多繼承情況下,super() 函數(shù)的實(shí)戰(zhàn)場(chǎng)景。

class A:
 def run(self):
 print('AAA')
class B:
 def run(self):
 print('BBB')
class C:
 def run(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 super().run()
d = D()
d.run()

此時(shí)輸出的結(jié)果是 AAA,可以看到 super 匹配到的數(shù)據(jù)是 A 類中的 run 函數(shù),也就是最左側(cè)類中的方法,下面修改一下各類中 run 函數(shù)的名稱,使其存在差異。

class A:
 def run1(self):
 print('AAA')
class B:
 def run2(self):
 print('BBB')
class C:
 def run3(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 調(diào)用 B 中 run2
 super().run2()
d = D()
d.run()

當(dāng)一個(gè)類繼承多個(gè)類時(shí),如果第一個(gè)父類中沒(méi)有提供該方法,當(dāng)前類實(shí)例就會(huì)通過(guò) __mro__ 屬性進(jìn)行向上搜索,如果到 object 類都沒(méi)有檢索到該方法,就會(huì)引發(fā) AttributeError 異常。

基于上述邏輯,我們可以擴(kuò)展一下,使用 super() 函數(shù)中的參數(shù)。

class A:
 def run(self):
 print('AAA')
class B:
 def run(self):
 print('BBB')
class C:
 def run(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 調(diào)用 C 中 run
 super(B, self).run()
d = D()
d.run()

此時(shí)輸出的結(jié)果是 CCC,該結(jié)果輸出表示了使用 super 函數(shù)之后,可以使用 super(類,self) 指定以哪個(gè)類為起點(diǎn)檢索父類中的方法,上述代碼設(shè)置的 B,就表示從 B 開(kāi)始檢索,后續(xù)找到了 C 類,其中包含 run() 方法,所以輸出 CCC。

__mro__ 屬性的說(shuō)明。

MRO 是 method resolution order,即方法解析順序,其本質(zhì)是繼承父類方法時(shí)的順序表。
在 Python 中可以使用內(nèi)置屬性 __mro__ 查看方法的搜索順序,例如下述代碼,重點(diǎn)查看輸出部分內(nèi)容。

class A:
 def run(self):
 print('AAA')
class B:
 def run(self):
 print('BBB')
class C:
 def run(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 調(diào)用 C 中 run
 super(B, self).run()
print(D.__mro__)

輸出的結(jié)果如下所示:

(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)

你可以修改一下繼承順序,然后得到不同的輸出結(jié)果。

(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class 'object'>)

在搜索方法的時(shí)候,是按照 __mro__ 的輸出結(jié)果從左到右進(jìn)行順序查找的,邏輯如下:

A. 找到方法,停止檢索;
B. 沒(méi)有找到,繼續(xù)檢索下一類;
C. 如果到最后都沒(méi)有找到,程序報(bào)錯(cuò)。

關(guān)于“Python中的super函數(shù)怎么用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Python中的super函數(shù)怎么用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI