欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析Python中接口與抽象基類的使用

 更新時(shí)間:2024年12月15日 08:24:39   作者:databook  
這篇文章主要為大家詳細(xì)介紹了Python中兩個(gè)為面向?qū)ο缶幊烫峁┑膹?qiáng)大工具接口和抽象基類的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

接觸Python比較早的朋友可能都有這樣的體會(huì),Python語(yǔ)言雖然也支持面向?qū)ο蟮木幊谭绞剑?/p>

但是,不像那些純面向?qū)ο蟮恼Z(yǔ)言(比如Java.NET)那樣嚴(yán)格和規(guī)范。

隨著項(xiàng)目的規(guī)模逐步擴(kuò)大之后,想要以一種清晰、可維護(hù)和可擴(kuò)展的方式定義和實(shí)施對(duì)象的行為就變得越來(lái)越困難。

今天介紹的Python中兩個(gè)為面向?qū)ο缶幊烫峁┑膹?qiáng)大工具:接口抽象基類。

它們的英文分別為ProtocolsABC(Abstract Base Classes)。

ProtocolsPython3.8才開始引入的,有的地方也翻譯成協(xié)議,我感覺(jué)翻譯成接口更熟悉一些。

ABC引入的比較早,在Python3之后得到了改進(jìn)和優(yōu)化,現(xiàn)在和其他語(yǔ)言的抽象類相比,差別不大。

1. 接口(Protocols)

Python3.8開始在類型模塊中引入的接口Protocols的概念,它提供了一種無(wú)需顯式繼承即可定義接口的方法。

接口Protocols定義了一組方法或?qū)傩?,只要一個(gè)對(duì)象實(shí)現(xiàn)了這些方法或?qū)傩裕捅灰暈闈M足該接口。

下面通過(guò)一個(gè)示例來(lái)幫助理解Protocols的使用,如果有面向?qū)ο缶幊痰慕?jīng)驗(yàn),很容易就能理解這個(gè)概念。

這個(gè)示例來(lái)自最近用的一個(gè)量化交易系統(tǒng)的一部分,這個(gè)功能需要從不同的來(lái)源獲取數(shù)據(jù),然后進(jìn)行分析,最后將分析結(jié)果以不同的方式輸出。

這三個(gè)步驟(獲取數(shù)據(jù),分析和輸出)中,

假設(shè)獲取數(shù)據(jù)的來(lái)源有網(wǎng)絡(luò)(API),文件(CSV)和數(shù)據(jù)庫(kù)3種;

分析的步驟是統(tǒng)一的;輸出的方式假設(shè)也有多種,比如郵件,短信等等。

根據(jù)這個(gè)描述,使用Protocols構(gòu)建的獲取數(shù)據(jù)和分析部分的代碼如下:

輸出的部分暫時(shí)不管

from typing import Protocol


# 輸入數(shù)據(jù)的接口
class InputData(Protocol):
    def get_data(self) -> str:
        pass


class APIHandler:
    def get_data(self) -> str:
        print("get_data from API")
        return "get data from API"


class CSVHandler:
    def get_data(self) -> str:
        print("get_data from CSV")
        return "get data from CSV"


class SqliteHandler:
    def get_data(self) -> str:
        print("get_data from SQLITE DATABASE")
        return "get data from SQLITE DATABASE"


# 分析數(shù)據(jù)
def analysis(i: InputData):
    data = i.get_data()

    print("開始處理數(shù)據(jù)...")

InputData繼承了Protocol,其中定義了接口的函數(shù)get_data。

只要實(shí)現(xiàn)了get_dataclass,比如APIHandler,CSVHandlerSqliteHandler,都可以當(dāng)做InputData類型。

從代碼可以看出,我們不需要用APIHandler去繼承InputData,只要實(shí)現(xiàn)InputData中的所有方法就可以了。

這種靈活性確保了系統(tǒng)的可擴(kuò)展性,我們可以添加新的數(shù)據(jù)源類型,而無(wú)需修改現(xiàn)有代碼。

接下來(lái)我們測(cè)試上面的代碼是否可以正常使用:

if __name__ == "__main__":
    i = APIHandler()
    analysis(i)
    print("\n")

    i = CSVHandler()
    analysis(i)
    print("\n")

    i = SqliteHandler()
    analysis(i)
    print("\n")

運(yùn)行結(jié)果:

$  python.exe .\protocol_abc.py
get_data from API
開始處理數(shù)據(jù)...

get_data from CSV
開始處理數(shù)據(jù)...

get_data from SQLITE DATABASE
開始處理數(shù)據(jù)...

2. 抽象基類(ABC)

Protocol非常具有靈活性,但有時(shí)我們需要更結(jié)構(gòu)化的方法,這就是抽象基類 (ABC) 的用武之地。

ABC 是一種通過(guò)定義子類必須實(shí)現(xiàn)的嚴(yán)格接口來(lái)強(qiáng)制執(zhí)行一致行為的工具。

Protocol不同,ABC 需要顯式繼承,因此當(dāng)我們希望在代碼中明確定義層次結(jié)構(gòu)時(shí),ABC是更好的選擇。

接著實(shí)現(xiàn)上一節(jié)示例中的輸出部分,每種不同的輸出需要不同的配置,

比如輸出到郵件需要先配置郵箱的賬號(hào)信息,輸出到短信需要配置手機(jī)信息等等。

在這里,我們使用 ABC 來(lái)實(shí)現(xiàn)輸出的基類。

# 輸出的抽象基類
class OutputResult(ABC):
    def __init__(self):
        self.settings: dict = {}

    @abstractmethod
    def send(self, data: str):
        pass

    @abstractmethod
    def config(self, settings: dict):
        pass


class OutputMail(ABC):
    def send(self, data: str):
        print(f"send {data} to {self.settings['name']}")

    def config(self, settings: dict):
        self.settings = settings


class OutputMessage(ABC):
    def send(self, data: str):
        print(f"send {data} to {self.settings['name']}")

    def config(self, settings: dict):
        self.settings = settings

這里使用抽象基類的原因是輸出時(shí),并不是簡(jiǎn)單的調(diào)用send方法就可以的,還需要配置輸出的參數(shù),

所以用帶有結(jié)構(gòu)的抽象基類更好。

加上輸出之后,上一節(jié)中的分析函數(shù)也改為:

# 分析數(shù)據(jù)
def analysis(i: InputData, o: OutputResult):
    data = i.get_data()

    print("開始處理數(shù)據(jù)...")
    data = data.replace("get data from ", "")

    o.send(data)

測(cè)試的代碼如下:

if __name__ == "__main__":
    i = APIHandler()
    o = OutputMail()
    o.config({"name": "aaa@bbb.com"})
    analysis(i, o)
    print("\n")

    i = CSVHandler()
    o = OutputMessage()
    o.config({"name": "13911123456"})
    analysis(i, o)
    print("\n")

    i = SqliteHandler()
    o = OutputMail()
    o.config({"name": "xyz@www.com"})
    analysis(i, o)
    print("\n")

運(yùn)行結(jié)果:

$  python.exe .\protocol_abc.py
get_data from API
開始處理數(shù)據(jù)...
send API to aaa@bbb.com

get_data from CSV
開始處理數(shù)據(jù)...
send CSV to 13911123456

get_data from SQLITE DATABASE
開始處理數(shù)據(jù)...
send SQLITE DATABASE to xyz@www.com

3. 兩者的選擇

當(dāng)我們?cè)趯?shí)際的開發(fā)設(shè)計(jì)中,應(yīng)該如何選擇ProtocolABC呢?

其實(shí),ProtocolABC之間的選擇并不是非黑即白,這通常取決于項(xiàng)目的背景和你的目標(biāo)。

一般來(lái)說(shuō),下面這些情況我們優(yōu)先選擇使用Protocol

  • 你正在使用現(xiàn)有代碼或希望集成第三方庫(kù)
  • 靈活性是首要任務(wù),你不想強(qiáng)制執(zhí)行嚴(yán)格的層次結(jié)構(gòu)
  • 來(lái)自不相關(guān)的類層次結(jié)構(gòu)的對(duì)象需要共享行為

而下面這些情況,優(yōu)先選擇ABC

  • 正在從頭開始設(shè)計(jì)一個(gè)系統(tǒng),并且需要加強(qiáng)結(jié)構(gòu)
  • 類之間的關(guān)系是可預(yù)測(cè)的,并且繼承是有意義的
  • 共享功能或默認(rèn)行為可以減少重復(fù)并提高一致性

4. 總結(jié)

總的來(lái)說(shuō),ProtocolABC不是互相競(jìng)爭(zhēng)的兩種工具,它們是互補(bǔ)的。

我使用Protocol將類型安全改造到遺留系統(tǒng)中,而不需要大量重構(gòu)。

另一方面,如果我在從頭開始構(gòu)建一個(gè)結(jié)構(gòu)和一致性至關(guān)重要的系統(tǒng)時(shí),會(huì)使用 ABC。

在決定使用哪個(gè)時(shí),請(qǐng)考慮項(xiàng)目的靈活性需求和長(zhǎng)期目標(biāo)。

Protocol提供靈活性和無(wú)縫集成,而 ABC 有助于建立結(jié)構(gòu)和一致性。

通過(guò)了解它們各自的優(yōu)勢(shì),你可以選擇合適的方式來(lái)構(gòu)建健壯、可維護(hù)的 Python 系統(tǒng)。

到此這篇關(guān)于淺析Python中接口與抽象基類的使用的文章就介紹到這了,更多相關(guān)Python接口與抽象基類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python密碼學(xué)各種加密模塊教程

    python密碼學(xué)各種加密模塊教程

    這篇文章主要為大家介紹了python密碼學(xué)各種加密模塊教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • matplotlib繪制餅圖的基本配置(萬(wàn)能模板案例)

    matplotlib繪制餅圖的基本配置(萬(wàn)能模板案例)

    餅圖是常見的一種圖表形式,本文主要介紹了matplotlib繪制餅圖的基本配置(萬(wàn)能模板案例),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 使用python將圖片改為灰度圖或黑白圖

    使用python將圖片改為灰度圖或黑白圖

    使用python將圖片改為灰度圖或黑白圖有三種方式,分別是是使用cv2庫(kù)和PIL庫(kù)來(lái)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Python?pyecharts?Boxplot箱線圖的實(shí)現(xiàn)

    Python?pyecharts?Boxplot箱線圖的實(shí)現(xiàn)

    本文主要介紹了Python?pyecharts?Boxplot箱線圖的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 在Django模型中的Mysql安裝全過(guò)程

    在Django模型中的Mysql安裝全過(guò)程

    這篇文章主要介紹了在Django模型中的Mysql安裝全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Python對(duì)數(shù)據(jù)進(jìn)行插值和下采樣的方法

    Python對(duì)數(shù)據(jù)進(jìn)行插值和下采樣的方法

    今天小編就為大家分享一篇Python對(duì)數(shù)據(jù)進(jìn)行插值和下采樣的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Python 將 QQ 好友頭像生成祝福語(yǔ)的實(shí)現(xiàn)代碼

    Python 將 QQ 好友頭像生成祝福語(yǔ)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了用 Python 將 QQ 好友頭像生成祝福語(yǔ)的實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Python實(shí)現(xiàn)Word批量轉(zhuǎn)PDF的小工具

    Python實(shí)現(xiàn)Word批量轉(zhuǎn)PDF的小工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python復(fù)刻一個(gè)Word批量轉(zhuǎn)PDF的小工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-05-05
  • python中windows鏈接linux執(zhí)行命令并獲取執(zhí)行狀態(tài)的問(wèn)題小結(jié)

    python中windows鏈接linux執(zhí)行命令并獲取執(zhí)行狀態(tài)的問(wèn)題小結(jié)

    這篇文章主要介紹了python中windows鏈接linux執(zhí)行命令并獲取執(zhí)行狀態(tài),由于工具是pyqt寫的所以牽扯到用python鏈接linux的問(wèn)題,這里記錄一下一些碰到的問(wèn)題,需要的朋友可以參考下
    2022-11-11
  • Python實(shí)現(xiàn)計(jì)算兩個(gè)指定日期相差幾年幾月幾日

    Python實(shí)現(xiàn)計(jì)算兩個(gè)指定日期相差幾年幾月幾日

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)計(jì)算兩個(gè)日期之間相差多少年,多少月,多少天,文中的的示例代碼講解詳細(xì),需要的可以參考下
    2024-02-02

最新評(píng)論