最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何使用Python基于接口編程的方法實現(xiàn)

 更新時間:2021年11月17日 09:07:11   作者:somenzz  
本文主要介紹了如何使用Python基于接口編程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

軟件行業(yè),唯一不變的就是變化。產(chǎn)品經(jīng)理會變,產(chǎn)品需求會變,代碼同樣要跟著變。

不同的代碼設計,變化所帶來的工作量更是不同,有的每改一次需求,近乎一次重構(gòu),而有的只需要修改一個配置文件,或者在類里添加一行代碼。當然比較好的代碼設計,由于有著良好的可擴展性,高內(nèi)聚,低耦合,因而易維護, 以少變應萬變。如果才能有好的代碼設計,就需要我們學習設計模式。今天為你分享的是在Python中,如何基于接口編程。

1994 年 GoF 的《設計模式》一書中有一個重要的原則就是:基于接口而非實現(xiàn)編程,英文源文是「Program to an interface,not an implementaion」,這里的所說的 interface,并不是特定編程語言中的接口,它是語言無關的,是指開發(fā)者提供給使用者的一個功能列表,理解了這一點非常重要。接口在 java 語言中是有關鍵字 interface 來實現(xiàn)的,java 不支持類的多重繼承,但支持接口的多重繼承,所在 java 開發(fā)者對接口非常熟悉了,Python 其實完全不需要 Java 那樣的設計,但可以借鑒接口的優(yōu)點。

先通過一個實例來了解下接口到底解決什么問題。

比如你正在實現(xiàn)一個圖片上傳功能,目前采用七牛云來存儲,你的類可能是這樣的。

class QnyImageStore(object):

    def getToken():
        pass

    def upload_qny(self,image):
        print("Qny upload.")
        #do something
    
    def download_qny(self,image):
        print("Qny download.")
        #do something

實際的開發(fā)中,代碼會有很多行,函數(shù)也不止三個,它被成百上千個地方被調(diào)用,分散在好幾百個文件中。 過了一段時間,公司自建了私有云,要求不能再使用七牛云了,要改成自己的云存儲,于是你不得不重新寫一個類:

class OwnImageStore(object):

    def upload_own(self,image):
        print("Qny upload.")
        #do something
    
    def download_own(self,image):
        print("Qny download.")
        #do something

然后你在使用七牛去的地方,都進行替換,還要替換函數(shù)的名稱,最后還要多次測試,生活哪一處沒有考慮到,運行報錯。好不容易改好了,突然有一天,需求又變了,由于自己的云服務經(jīng)常出問題,于是要換阿里云。經(jīng)過上次的一翻痛苦折騰,看到這次又要改,直接吐血。

其實問題就在于你寫的代碼不夠通用,命名不夠抽象。假如你的類的函數(shù)命名使用 upload,download 這樣,那么你修改的代碼量可能會減少到一半,只替換一下類名就可以了。實際上,我們可以使用接口來減少代碼的改動量:通過接口和實現(xiàn)相分離的模式,封裝不穩(wěn)定的實現(xiàn),暴露穩(wěn)定的接口。上下游系統(tǒng)在使用我們開發(fā)的功能時,只需要使用接口中聲明的函數(shù)列表,這樣當實現(xiàn)發(fā)生變化的時候,上游系統(tǒng)的代碼基本上不需要做改動,以此來降低耦合性,提高擴展性。下面就該問題,提供一種基于接口的代碼實現(xiàn)方式。

定義一個接口

from abc import ABCMeta, abstractmethod

class ImageStore(metaclass = ABCMeta):
    
    @abstractmethod
    def upload(self,image): 
        pass
        #raise NotImplementedError

    @abstractmethod
    def download(self,image): 
        pass
        #raise NotImplementedError

定義了該接口之后,任何繼承該接口的類要想正確的使用,必須重寫 upload 和 download 方法,否則均會拋出異常,這里我們不需要自己在接口中拋出異常,標準庫 abc 已經(jīng)為我們做好了這些工作。

定義類,繼承接口

目的其實是是為了強制約束,也就是說必須實現(xiàn) upload 和 download 方法,在編譯時進行檢查,確保程序的健壯。

class OwnImageStore2(ImageStore):

    def upload(self,image):
        print("Own upload.")
        #do something
    
    def download(self,image):
        print("Own download.")
        #do something

class QnyImageStore2(ImageStore):

    def getToken():
        pass

    def upload(self,image):
        print("Qny upload.")

    def download(self,image):
        print("Qny download.")
        #do something

接下來,我們定義一個接口,可以自動的根據(jù)類型來選擇調(diào)用對應對象的方法。

class UsedStore(object):

    def __init__(self, store):
        if not isinstance(store, ImageStore): raise Exception('Bad interface')
        self._store = store

    def upload(self):
        self._store.upload('image')

    def download(self):
        self._store.download('image')

最后,我們可以在配置文件中指明我們使用的是哪個具體的接口:

#在其他文件中,應該這樣調(diào)用
img = QnyImageStore2()
# img = OwnImageStore2() 把這些放在配置文件中,只需要更新配置文件就可以替換 
store = UsedStore(img)
store.upload()
store.download()

這樣,后面再增加新的圖片存儲,我們只需要添加相應的類,繼承接口,并修改下配置文件即可,減輕大量的代碼修改工作。

Python 抽象基類的介紹 (PEP3119)

python 標準庫 abc,全稱是Abstract Base Classes,它提供以下功能:

  • 一種重載isinstance()和issubclass()的方法
  • 一個新的模塊abc作為“Abstract Base Classes支持框架”。它定義了一個用于abc的元類和一個可以用來定義抽象方法的裝飾器
  • 容器和迭代器的特定抽象基類,將被添加到 collections 模塊

基本原理:

在面向?qū)ο蟪绦蛟O計領域,與對象交互的設計模式可以分為兩個基本類別,即“調(diào)用”和“檢查”。

調(diào)用是指通過調(diào)用對象的方法與對象進行交互。 通常,這會與多態(tài)性結(jié)合使用,因此調(diào)用給定方法可能會根據(jù)對象的類型運行不同的代碼。

檢查是指外部代碼(在對象的方法之外)檢查該對象的類型或?qū)傩?,并根?jù)該信息來決定如何處理該對象的能力。

兩種使用模式均服務于相同的通用目的,即能夠以統(tǒng)一的方式支持處理多種多樣且可能新穎的對象,但同時允許為每種不同類型的對象定制處理決策。

在經(jīng)典的 OOP 理論中,調(diào)用是首選的設計模式,并且不鼓勵檢查,因為檢查被認為是較早的過程編程風格的產(chǎn)物。 但是,實際上,這種觀點過于教條和僵化,導致了某種設計僵化,與諸如 Python 之類的語言的動態(tài)特性大相徑庭。

特別是,通常需要以對象類的創(chuàng)建者無法預期的方式處理對象。 內(nèi)置到滿足該對象的每個可能用戶需求的每個對象方法中,并非總是最佳的解決方案。 而且,有許多強大的調(diào)度哲學與嚴格地封裝在對象中的經(jīng)典OOP行為要求形成鮮明對比,例如規(guī)則或模式匹配驅(qū)動的邏輯

另一方面,經(jīng)典的 OOP 理論家對檢查的批評之一是缺乏形式主義和被檢查內(nèi)容的特殊性質(zhì)。 在諸如 Python 這樣的語言中,幾乎可以通過外部代碼反映并直接訪問對象的任何方面,有很多不同的方法來測試對象是否符合特定的協(xié)議。 例如,如果詢問“此對象是否是可變序列容器?”,則可以尋找“列表”的基類,或者可以尋找名為“ getitem”的方法。 但是請注意,盡管這些測試看似顯而易見,但它們都不正確,因為其中一個會產(chǎn)生假陰性,而另一個會產(chǎn)生假陽性。

普遍同意的補救措施是對測試進行標準化,并將其分組為正式形式。 通過繼承機制或其他某種方式,通過與每個類關聯(lián)一組標準的可測試屬性,最容易做到這一點。 每個測試都帶有一組承諾:它包含有關類的一般行為的承諾,以及有關其他可用的類方法的承諾。

PEP為組織這些測試提出了一種特殊的策略,稱為抽象基類(ABC)。 ABC只是添加到對象的繼承樹中的Python類,以將對象的某些功能發(fā)送給外部檢查器。 使用isinstance()完成測試,并且特定ABC的存在意味著測試已通過。

此外,ABC定義了建立該類型特征行為的最少方法集。 根據(jù)對象的ABC類型區(qū)分對象的代碼可以相信,這些方法將始終存在。 這些方法中的每一個都附帶有ABC文檔中描述的廣義抽象語義定義。 這些標準的語義定義不是強制性的,但強烈建議使用。

像Python中的所有其他內(nèi)容一樣,這些承諾屬于紳士協(xié)議的性質(zhì),在這種情況下,這意味著盡管該語言確實執(zhí)行了ABC中做出的某些承諾,但具體類的實現(xiàn)者必須確保 剩下的保留下來。

看完上面的描述,你可以簡單的理解為,ABC 是一個基類,繼承它,你可以寫一個類似于 java 的接口,接口中的方法將始終存在,可以放心使用,不需要再進行探測。

PEP3119 還給了樣例代碼讓你理解:

from abc import ABCMeta, abstractmethod

class A(metaclass=ABCMeta):
    @abstractmethod
    def foo(self): pass

A()  # raises TypeError

class B(A):
    pass

B()  # raises TypeError

class C(A):
    def foo(self): print(42)

C()  # works

多的不說了,希望你可以正確地使用 ABC,同時強烈推薦,學習 Python,就看 Python 的官方文檔和 PEP 提案,這里有最權(quán)威的講解。

此外,設置模式也是非常重要的編程之術(shù)和編程之道,它是基本功,基本功如果不夠,把一臺戰(zhàn)斗機放你面前,你都不知道如何欣賞和品味。

掌握了設計模式,再看別人的代碼,你會擁有火眼金睛,哪些是戰(zhàn)斗機,哪些是拖拉機,對自己的學習和提升也非常有幫助,寫的代碼也會更加具有可維護性,可讀性,可擴展性,靈活性。

到此這篇關于如何使用Python基于接口編程的方法實現(xiàn)的文章就介紹到這了,更多相關Python基于接口編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于python讀取圖像的幾種方式匯總

    基于python讀取圖像的幾種方式匯總

    Python進行圖片處理,第一步就是讀取圖片,下面這篇文章主要給大家介紹了關于基于python讀取圖像的幾種方式的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • Python中字符串去空格的五種方法介紹與對比

    Python中字符串去空格的五種方法介紹與對比

    在?Python?中,去除字符串中的空格是一個常見的操作,這篇文章小編將為大家盤點一下python中常用的的去空格的方法,需要的可以參考一下
    2025-02-02
  • 一文帶你了解Python中的注釋及變量

    一文帶你了解Python中的注釋及變量

    這篇文章主要給大家介紹了關于Python中注釋及變量的相關資料,Python是一門動態(tài)類型的語言,因此無須提前聲明變量類型,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • python 字典中文key處理,讀取,比較方法

    python 字典中文key處理,讀取,比較方法

    今天小編就為大家分享一篇python 字典中文key處理,讀取,比較方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • python中異常報錯處理方法匯總

    python中異常報錯處理方法匯總

    之前在學習python的時候有整理過python異常處理的文章,不夠簡單也不夠完整,所以決定再整理一篇,算做補充,大家學習一下,就可以自己思考解決方法了,希望對大家能夠有所幫助
    2016-11-11
  • Python利用pymupdf實現(xiàn)簡單的PDF閱讀器

    Python利用pymupdf實現(xiàn)簡單的PDF閱讀器

    這篇文章主要為大家詳細介紹了Python如何利用pymupdf實現(xiàn)簡單的PDF閱讀器,并展示了PDF文件的內(nèi)容,文中的示例代碼講解詳細,需要的可以了解一下
    2023-08-08
  • TensorBoard 計算圖的查看方式

    TensorBoard 計算圖的查看方式

    今天小編就為大家分享一篇TensorBoard 計算圖的查看方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • python安裝virtualenv虛擬環(huán)境步驟圖文詳解

    python安裝virtualenv虛擬環(huán)境步驟圖文詳解

    這篇文章主要介紹了python安裝virtualenv虛擬環(huán)境步驟,本文通過圖文并茂的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • Python 使用PIL numpy 實現(xiàn)拼接圖片的示例

    Python 使用PIL numpy 實現(xiàn)拼接圖片的示例

    今天小編就為大家分享一篇Python 使用PIL numpy 實現(xiàn)拼接圖片的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 深入理解Python虛擬機中復數(shù)(complex)的實現(xiàn)原理及源碼剖析

    深入理解Python虛擬機中復數(shù)(complex)的實現(xiàn)原理及源碼剖析

    在本篇文章當中主要給大家介紹在 cpython 虛擬機當中是如何實現(xiàn) 復數(shù) complex 這個數(shù)據(jù)類型的,這個數(shù)據(jù)類型在 cpython 當中一應該是一個算比較簡單的數(shù)據(jù)類型了,非常容易理解
    2023-03-03

最新評論

临江市| 安化县| 宝坻区| 新泰市| 托里县| 宜君县| 遂宁市| 分宜县| 安达市| 九龙坡区| 綦江县| 阿鲁科尔沁旗| 茌平县| 永宁县| 沧源| 安徽省| 丹东市| 邢台县| 沁阳市| 广饶县| 资溪县| 荔浦县| 奎屯市| 略阳县| 中西区| 深水埗区| 金湖县| 泰州市| 武义县| 平泉县| 连城县| 清新县| 南丹县| 西林县| 玉树县| 赣州市| 孙吴县| 育儿| 灯塔市| 阳曲县| 上虞市|