您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家?guī)碛嘘P怎么在Python中實現面向接口編程,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
class Car: def run(self): pass class Benz(Car): def run(self): print("benz run") class BMW(Car): def run(self): print("bwm run") def run(car): car.run() if __name__ == "__main__": benz = Benz() bmw = BMW() run(benz) run(bmw)
代碼非常簡單,在 Python 中也沒有類似于 Java 中的 extends 關鍵字,只需要在類聲明末尾用括號包含基類即可。
這樣在每個子類中就能單獨實現業(yè)務邏輯,方便擴展和維護。
由于 Python 作為一個動態(tài)類型語言,無法做到 Java 那樣在編譯期間校驗一個類是否完全實現了某個接口的所有方法。
為此 Python 提供了解決辦法,那就是 abc(Abstract Base Classes) ,當我們將基類用 abc 聲明時就能近似做到:
import abc class Car(abc.ABC): @abc.abstractmethod def run(self): pass class Benz(Car): def run(self): print("benz run") class BMW(Car): pass def run(car): car.run() if __name__ == "__main__": benz = Benz() bmw = BMW() run(benz) run(bmw)
一旦有類沒有實現方法時,運行期間便會拋出異常:
bmw = BMW()
TypeError: Can't instantiate abstract class BMW with abstract methods run
雖然無法做到在運行之前(畢竟不需要編譯)進行校驗,但有總比沒有好。
以上兩種方式看似已經畢竟優(yōu)雅的實現面向接口編程了,但實際上也不夠 Pythonic。
在繼續(xù)之前我們先聊聊接口的本質到底是什么?
在 Java 這類靜態(tài)語言中面向接口編程是比較麻煩的,也就是我們常說的子類向父類轉型,因此需要編寫額外的代碼。
帶來的好處也是顯而易見,只需要父類便可運行。
但我們也不必過于執(zhí)著于接口,它本身只是一個協(xié)議、規(guī)范,并不特指 Java 中的 Interface,甚至有些語言壓根沒有這個關鍵字。
動態(tài)語言的特性也不需要強制校驗是否實現了方法。
在 Python 中我們可以利用鴨子類型來優(yōu)雅的實現面向接口編程。
在這之前先了解下鴨子類型,借用維基百科的說法:
“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子。”
我用大白話翻譯下就是:
即便兩個完全不想干的類,如果他們都實現了相同的方法,那就可以把他們當做同一類型的類來使用。
舉個簡單例子:
class Order: def create(self): pass class User: def create(self): pass def create(obj): obj.create() if __name__ == "__main__": order = Order() user = User() create(order) create(user)
這里的 order 和 user 本身完全沒有關系,只是他們都有相同方法,又得益于動態(tài)語言沒法校驗類型的特點,所以完全可以在運行的時候認為他們是同一種類型。
因此基于鴨子類型,之前的代碼我們可以稍作簡化:
class Car: def run(self): pass class Benz: def run(self): print("benz run") class BMW: def run(self): print("bwm run") def run(car): car.run() if __name__ == "__main__": benz = Benz() bmw = BMW() run(benz) run(bmw)
因為在鴨子類型中我們在意的是它的行為,而不是他們的類型;所以完全可以不用繼承便可以實現面向接口編程。
上述就是小編為大家分享的怎么在Python中實現面向接口編程了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。