在Python中實(shí)現(xiàn)函數(shù)重載的示例代碼
假設(shè)你有一個(gè)函數(shù)connect,它有一個(gè)參數(shù)address,這個(gè)參數(shù)可能是一個(gè)字符串,也可能是一個(gè)元組。例如:
connect('123.45.32.18:8080')
connect(('123.45.32.18', 8080))
你想在代碼里面兼容這兩種寫法,于是你可能會(huì)這樣寫代碼:
def connect(address):
if isinstance(address, str):
ip, port = address.split(':')
elif isinstance(address, tuple):
ip, port = address
else:
print('地址格式不正確')
這種寫法簡(jiǎn)單直接,但是如果參數(shù)的類型更多,那么你就需要寫很長(zhǎng)的 if-elif-elif-...-else 。代碼看起來就非常不美觀。
學(xué)習(xí)過 Java 的同學(xué),應(yīng)該對(duì)函數(shù)重載比較熟悉,可以定義幾個(gè)名字相同的函數(shù),但是他們的參數(shù)類型或者數(shù)量不同,從而實(shí)現(xiàn)不同的代碼邏輯。
在 Python 里面,參數(shù)的數(shù)量不同可以使用默認(rèn)參數(shù)來解決,不需要定義多個(gè)函數(shù)。那如果參數(shù)類型不同就實(shí)現(xiàn)不同的邏輯,除了上面的 if-else 外,我們還可以使用 functools 模塊里面的 singledispatch 裝飾器實(shí)現(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)
我們運(yùn)行一下這段代碼,大家看看根據(jù)參數(shù)的不同,有什么樣的不同效果:

可以看到,我們調(diào)用的函數(shù),始終都是 connect ,但是由于傳入?yún)?shù)的類型不同,它運(yùn)行的結(jié)果也不一樣。
我們使用 singledispatch 裝飾一個(gè)函數(shù),那么這個(gè)函數(shù)就是我們將會(huì)調(diào)用的函數(shù)。
這個(gè)函數(shù)在傳入?yún)?shù)不同時(shí)的具體實(shí)現(xiàn),通過下面注冊(cè)的函數(shù)來實(shí)現(xiàn)。注冊(cè)的時(shí)候使用 @我們定義的函數(shù)名.register 來注冊(cè)。被注冊(cè)的函數(shù)名叫什么無關(guān)緊要,所以這里我都直接使用下劃線代替。
被注冊(cè)的函數(shù)的第一個(gè)參數(shù),通過類型標(biāo)注來確定它應(yīng)該使用什么類型。當(dāng)我們調(diào)用我們定義的函數(shù)是,如果參數(shù)類型符合某個(gè)被注冊(cè)的函數(shù),那么就會(huì)執(zhí)行這個(gè)被注冊(cè)的函數(shù)。如果參數(shù)類型不滿足任何一個(gè)被注冊(cè)的函數(shù),那么就會(huì)執(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í),還有一個(gè)需要注意的點(diǎn),就是只有第一個(gè)參數(shù)的不同類型會(huì)被重載。后面的參數(shù)的類型變化會(huì)被自動(dòng)忽略。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
如何基于Python實(shí)現(xiàn)word文檔重新排版
這篇文章主要介紹了如何基于Python實(shí)現(xiàn)word文檔重新排版,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
詳解Django中異步任務(wù)之django-celery
這篇文章主要介紹了詳解Django中異步任務(wù)之django-celery,本文通過場(chǎng)景分析實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
解決Django transaction進(jìn)行事務(wù)管理踩過的坑
這篇文章主要介紹了解決Django transaction進(jìn)行事務(wù)管理踩過的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
利用Python將彩色圖像轉(zhuǎn)為灰度圖像的兩種方法
這篇文章主要給大家介紹了關(guān)于利用Python將彩色圖像轉(zhuǎn)為灰度圖像的兩種方法,以及python 批量將圖片轉(zhuǎn)為灰度圖的方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
python實(shí)現(xiàn)自動(dòng)發(fā)送報(bào)警監(jiān)控郵件
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)發(fā)送報(bào)警監(jiān)控郵件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Python圖像文字識(shí)別詳解(附實(shí)戰(zhàn)代碼)
這篇文章主要給大家介紹了關(guān)于Python圖像文字識(shí)別的相關(guān)資料,本文介紹使用python進(jìn)行圖像的文字識(shí)別,將圖像中的文字提取出來,可以幫助我們完成很多有趣的事情,需要的朋友可以參考下2024-02-02

