在Python中實現(xiàn)函數(shù)重載的示例代碼
假設(shè)你有一個函數(shù)connect,它有一個參數(shù)address,這個參數(shù)可能是一個字符串,也可能是一個元組。例如:
connect('123.45.32.18:8080') connect(('123.45.32.18', 8080))
你想在代碼里面兼容這兩種寫法,于是你可能會這樣寫代碼:
def connect(address): if isinstance(address, str): ip, port = address.split(':') elif isinstance(address, tuple): ip, port = address else: print('地址格式不正確')
這種寫法簡單直接,但是如果參數(shù)的類型更多,那么你就需要寫很長的 if-elif-elif-...-else
。代碼看起來就非常不美觀。
學(xué)習(xí)過 Java 的同學(xué),應(yīng)該對函數(shù)重載比較熟悉,可以定義幾個名字相同的函數(shù),但是他們的參數(shù)類型或者數(shù)量不同,從而實現(xiàn)不同的代碼邏輯。
在 Python 里面,參數(shù)的數(shù)量不同可以使用默認參數(shù)來解決,不需要定義多個函數(shù)。那如果參數(shù)類型不同就實現(xiàn)不同的邏輯,除了上面的 if-else
外,我們還可以使用 functools
模塊里面的 singledispatch
裝飾器實現(xiàn)函數(shù)重載。
我們來寫一段代碼:
from functools import singledispatch @singledispatch def connect(address): print(f' 傳輸參數(shù)類型為:{type(address)},不是有效類型') @connect.register def _(address: str): ip, port = address.split(':') print(f'參數(shù)為字符串,IP是:{ip}, 端口是:{port}') @connect.register def _(address: tuple): ip, port = address print(f'參數(shù)為元組,IP是:{ip}, 端口是:{port}') connect('123.45.32.18:8080') connect(('123.45.32.18', 8080)) connect(123)
我們運行一下這段代碼,大家看看根據(jù)參數(shù)的不同,有什么樣的不同效果:
可以看到,我們調(diào)用的函數(shù),始終都是 connect
,但是由于傳入?yún)?shù)的類型不同,它運行的結(jié)果也不一樣。
我們使用 singledispatch
裝飾一個函數(shù),那么這個函數(shù)就是我們將會調(diào)用的函數(shù)。
這個函數(shù)在傳入?yún)?shù)不同時的具體實現(xiàn),通過下面注冊的函數(shù)來實現(xiàn)。注冊的時候使用 @我們定義的函數(shù)名.register
來注冊。被注冊的函數(shù)名叫什么無關(guān)緊要,所以這里我都直接使用下劃線代替。
被注冊的函數(shù)的第一個參數(shù),通過類型標(biāo)注來確定它應(yīng)該使用什么類型。當(dāng)我們調(diào)用我們定義的函數(shù)是,如果參數(shù)類型符合某個被注冊的函數(shù),那么就會執(zhí)行這個被注冊的函數(shù)。如果參數(shù)類型不滿足任何一個被注冊的函數(shù),那么就會執(zhí)行我們的原函數(shù)。
使用類型標(biāo)注來指定參數(shù)類型是從 Python 3.7才引入的新特性。在 Python 3.6或之前的版本,我們需要通過 @我們定義的函數(shù)名.register(類型)
來指定類型,例如:
from functools import singledispatch @singledispatch def connect(address): print(f' 傳輸參數(shù)類型為:{type(address)},不是有效類型') @connect.register(str) def _(address): ip, port = address.split(':') print(f'參數(shù)為字符串,IP是:{ip}, 端口是:{port}') @connect.register(tuple) def _(address): ip, port = address print(f'參數(shù)為元組,IP是:{ip}, 端口是:{port}')
同時,還有一個需要注意的點,就是只有第一個參數(shù)的不同類型會被重載。后面的參數(shù)的類型變化會被自動忽略。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python向MySQL批量插數(shù)據(jù)的實例講解
下面小編就為大家分享一篇Python向MySQL批量插數(shù)據(jù)的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03Python3實現(xiàn)的回文數(shù)判斷及羅馬數(shù)字轉(zhuǎn)整數(shù)算法示例
這篇文章主要介紹了Python3實現(xiàn)的回文數(shù)判斷及羅馬數(shù)字轉(zhuǎn)整數(shù)算法,涉及Python數(shù)值運算、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2019-03-03Python3連接MySQL(pymysql)模擬轉(zhuǎn)賬實現(xiàn)代碼
這篇文章主要介紹了Python3連接MySQL(pymysql)模擬轉(zhuǎn)賬實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-05-05