假設你有一個函式connect,它有一個引數address,這個引數可能是一個字串,也可能是一個元組,例如:


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('地址格式不正確')
復制代碼
這種寫法簡單直接,但是如果引數的型別更多,那么你就需要寫很長的 if-elif-elif-...-else,代碼看起來就非常不美觀,
學習過 Java 的同學,應該對函式多載比較熟悉,可以定義幾個名字相同的函式,但是他們的引數型別或者數量不同,從而實作不同的代碼邏輯,
在 Python 里面,引數的數量不同可以使用默認引數來解決,不需要定義多個函式,那如果引數型別不同就實作不同的邏輯,除了上面的 if-else外,我們還可以使用functools模塊里面的singledispatch裝飾器實作函式多載,
我們來寫一段代碼:
from functools import singledispatch
@singledispatch
def connect(address):
print(f' 傳輸引數型別為:{type(address)},不是有效型別')
@connect.register
def _(address: str):
ip, port = address.split(':')
print(f'引數為字串,IP是:{ip}, 埠是:{port}')
@connect.register
def _(address: tuple):
ip, port = address
print(f'引數為元組,IP是:{ip}, 埠是:{port}')
connect('123.45.32.18:8080')
connect(('123.45.32.18', 8080))
connect(123)
復制代碼
- 我們運行一下這段代碼,大家看看根據引數的不同,有什么樣的不同效果:

可以看到,我們呼叫的函式,始終都是connect,但是由于傳入引數的型別不同,它運行的結果也不一樣,
我們使用singledispatch裝飾一個函式,那么這個函式就是我們將會呼叫的函式,
這個函式在傳入引數不同時的具體實作,通過下面注冊的函式來實作,注冊的時候使用@我們定義的函式名.register來注冊,被注冊的函式名叫什么無關緊要,所以這里我都直接使用下劃線代替,
被注冊的函式的第一個引數,通過型別標注來確定它應該使用什么型別,當我們呼叫我們定義的函式是,如果引數型別符合某個被注冊的函式,那么就會執行這個被注冊的函式,如果引數型別不滿足任何一個被注冊的函式,那么就會執行我們的原函式,
使用型別標注來指定引數型別是從 Python 3.7才引入的新特性,在 Python 3.6或之前的版本,我們需要通過@我們定義的函式名.register(型別)來指定型別,例如:
from functools import singledispatch
@singledispatch
def connect(address):
print(f' 傳輸引數型別為:{type(address)},不是有效型別')
@connect.register(str)
def _(address):
ip, port = address.split(':')
print(f'引數為字串,IP是:{ip}, 埠是:{port}')
@connect.register(tuple)
def _(address):
ip, port = address
print(f'引數為元組,IP是:{ip}, 埠是:{port}')
復制代碼
同時,還有一個需要注意的點,就是只有第一個引數的不同型別會被多載,后面的引數的型別變化會被自動忽略,
最后注意:不管你是為了Python就業還是興趣愛好,記住:專案開發經驗永遠是核心,如果你沒有2020最新python入門到高級實戰視頻教程,可以去小編的Python交流.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,里面很多新python教程專案,還可以跟老司機交流討教!
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/156829.html
標籤:Python
