Python強(qiáng)制子類重寫父類的兩種方法實(shí)現(xiàn)
Python v3.7.0
方案一(推薦)
定義抽象基類,只要把一個(gè)方法定義成抽象方法,那解釋器就會(huì)要求子類必須重寫這個(gè)方法,要注意的是,如果抽象方法沒有被重寫,那么子類在實(shí)例化時(shí),就會(huì)拋出TypeError異常,而不需要等到調(diào)用函數(shù)。
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass class Dog(Animal): def run(self): pass if __name__ == '__main__': dog = Dog()
運(yùn)行以上代碼,會(huì)拋出異常:
TypeError: Can't instantiate abstract class Dog with abstract methods speak
只有在Dog子類中,重寫speak方法,才可以正常實(shí)例化子類。
方案二
指定父類方法拋出NotImplementedError異常
class Animal1(): def speak(self): raise NotImplementedError class Dog1(Animal1): def run(self): pass if __name__ == '__main__': dog = Dog1() dog.speak()
子類中若沒有重寫speak方法,也可以正常實(shí)例化,但是調(diào)用此方法時(shí),就會(huì)拋出NotImplementedError異常。
補(bǔ)充
在父類中定義的私有方法,其作用范圍僅在當(dāng)前類,若在子類中重寫,實(shí)際上并不會(huì)起效果,原因:以雙下劃線前綴開頭的屬性或方法,Python解釋器會(huì)重寫其名稱,以便在類被擴(kuò)展的時(shí)候不容易產(chǎn)生沖突,這被稱之為名稱修飾(name mangling),如下所示:
class Test: def __init__(self): self.__foo = True def __bar(self): return "bar" t = Test() print(dir(t)) print(t._Test__foo) print(t._Test__bar())
輸出內(nèi)容如下,注意列表前兩個(gè)值,這同時(shí)也說明在Python中是沒有絕對(duì)私有的變量或方法的。
['_Test__bar', '_Test__foo', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
True
bar
在類的繼承中,如果在子類中重寫了父類方法,但有時(shí)也希望能同時(shí)實(shí)現(xiàn)父類的功能,最常見的場(chǎng)景之一就是父類構(gòu)造方法中的初始值無法被繼承,可以在子類中使用super 函數(shù)來調(diào)用父類中的方法,特別是多重繼承的情況;如下面的例子:
class Animal: def __init__(self): self.hungry = True def eat(self): if self.hungry: print('No!') else: print('Yes!') class Bird(Animal): def __init__(self): self.song = '~~~' def sing(self): print(self.song) bird = Bird() bird.sing() # 正常 bird.eat() # 拋出異常:AttributeError: 'Bird' object has no attribute 'hungry'
解決的方法是在子類的構(gòu)造函數(shù)中,使用super方法調(diào)用父類的構(gòu)造函數(shù),如下:
class Bird(Animal): def __init__(self): super().__init__() self.song = '~~~'
到此這篇關(guān)于Python強(qiáng)制子類重寫父類的兩種方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python強(qiáng)制子類重寫父類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python多線程實(shí)現(xiàn)同時(shí)執(zhí)行兩個(gè)while循環(huán)的操作
這篇文章主要介紹了python多線程實(shí)現(xiàn)同時(shí)執(zhí)行兩個(gè)while循環(huán)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05pycharm調(diào)試功能如何實(shí)現(xiàn)跳到循環(huán)的某一步
這篇文章主要介紹了pycharm調(diào)試功能如何實(shí)現(xiàn)跳到循環(huán)的某一步問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08使用Python和OpenCV進(jìn)行視覺圖像分割的代碼示例
在圖像處理領(lǐng)域,圖像分割是一項(xiàng)基礎(chǔ)且關(guān)鍵的技術(shù),它涉及到將圖像劃分為若干個(gè)具有特定屬性的區(qū)域,本文將通過一個(gè)實(shí)踐項(xiàng)目,展示如何使用Python編程語言,結(jié)合OpenCV庫,對(duì)一張玫瑰花的圖片進(jìn)行圖像分割,需要的朋友可以參考下2025-01-01Python圖像閾值化處理及算法比對(duì)實(shí)例解析
這篇文章主要介紹了Python圖像閾值化處理及算法比對(duì)實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Python利用遞歸實(shí)現(xiàn)文件的復(fù)制方法
今天小編就為大家分享一篇Python利用遞歸實(shí)現(xiàn)文件的復(fù)制方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python?Scrapy庫構(gòu)建基礎(chǔ)爬蟲
這篇文章主要為大家介紹了Python?Scrapy庫構(gòu)建基礎(chǔ)爬蟲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08