天天看點

python函數重載機制_在Python中實作函數重載,60%的人都不會

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)

複制代碼

我們運作一下這段代碼,大家看看根據參數的不同,有什麼樣的不同效果:

python函數重載機制_在Python中實作函數重載,60%的人都不會

可以看到,我們調用的函數,始終都是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教程項目,還可以跟老司機交流讨教!

本文的文字及圖檔來源于網絡加上自己的想法,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。