淺析python繼承與多重繼承
記住以下幾點(diǎn):
直接子類化內(nèi)置類型(如dict,list或str)容易出錯(cuò),因?yàn)閮?nèi)置類型的方法通常會(huì)忽略用戶覆蓋的方法,不要子類化內(nèi)置類型,用戶自定義的類應(yīng)該繼承collections模塊。
def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) # 錯(cuò)誤案例 class AnswerDict(dict): def __getitem__(self, item): # 錯(cuò)誤案例 return 42 import collections class DoppelDict2(collections.UserDict): # 正確案例 def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict2(collections.UserDict): # 正確案例 def __getitem__(self, item): return 42
多重繼承有關(guān)的另一個(gè)問題就是:如果同級(jí)別的超類定義了同名屬性.Python如何確定使用哪個(gè)?
class DoppelDict(dict): def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict(dict): def __getitem__(self, item): return 42 import collections class DoppelDict2(collections.UserDict): def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict2(collections.UserDict): def __getitem__(self, item): return 42 class A: def ping(self): print('Ping:', self) class B(A): def pong(self): print('pong:', self) class C(A): def pong(self): print('PONG:', self) class D(B, C): def ping(self): super().ping() print('post-ping:', self) def pingpong(self): self.ping() super().ping() self.pong() super().pong() C.pong(self) if __name__ == '__main__': d = D() print(d.pong()) # 輸出來源于B print(C.pong(d)) #輸出來源于C 超類的方法都可以直接調(diào)用,此時(shí)要把實(shí)例作為顯示參數(shù)傳入.
python能區(qū)別調(diào)用的是哪個(gè)方法,通過方法解析順序
>>> D.mro()
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
若想把方法調(diào)用委托給超類,推薦的方式是使用內(nèi)置的super()函數(shù).
以下是對(duì)于d.pingpong()方法的解讀
>>> self.ping()
Ping: <__main__.D object at 0x000002213877F2B0> post-ping: <__main__.D object at 0x000002213877F2B0> 第一個(gè)調(diào)用的是self.ping(),運(yùn)行的是是D類的ping,方法.
第二個(gè)調(diào)用的的是super().ping(),跳過D類的ping方法,找到A類的ping方法.Ping: <__main__.D object at 0x000002213877F2B0>
第三個(gè)調(diào)用的是self.pong()方法,根據(jù)__mro__,找到B類實(shí)現(xiàn)的pong方法. pong: <__main__.D object at 0x000002213877F2B0>
第四個(gè)調(diào)用時(shí)super().pong(),也是根據(jù)__mro__,找到B類實(shí)現(xiàn)的pong方法. pong: <__main__.D object at 0x000002213877F2B0>
第五個(gè)調(diào)用的是C.pong(self),忽略了__mro__,找到的是C類實(shí)現(xiàn)的pong方法. PONG: <__main__.D object at 0x000002213877F2B0>
相關(guān)文章
Python自動(dòng)檢測(cè)SSL證書是否過期的實(shí)現(xiàn)示例
SSL證書是有有效期的,一旦過期就會(huì)失效,從而帶來安全風(fēng)險(xiǎn),本文主要介紹了Python自動(dòng)檢測(cè)SSL證書是否過期的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11python列表操作之extend和append的區(qū)別實(shí)例分析
這篇文章主要介紹了python列表操作之extend和append的區(qū)別,實(shí)例分析了extend方法和append方法使用上的區(qū)別,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07Python實(shí)現(xiàn)刪除文件中含“指定內(nèi)容”的行示例
這篇文章主要介紹了Python實(shí)現(xiàn)刪除文件中含“指定內(nèi)容”的行功能,涉及Python針對(duì)文件讀取及字符串遍歷、判斷等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06Python3.6日志Logging模塊簡(jiǎn)單用法示例
這篇文章主要介紹了Python3.6日志Logging模塊簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了Python3.6環(huán)境下日志Logging模塊設(shè)置格式、文件流輸出相關(guān)操作技巧,需要的朋友可以參考下2018-06-06python?matplotlib繪圖過程中設(shè)置線條顏色實(shí)戰(zhàn)舉例
Matplotlib是一個(gè)用于數(shù)據(jù)可視化和創(chuàng)建交互式圖表的Python庫(kù),下面這篇文章主要給大家介紹了關(guān)于python?matplotlib繪圖過程中設(shè)置線條顏色的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05