如何在Python中實現函式過載
假設你有一個函式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}')
同時,還有一個需要注意的點,就是隻有第一個引數的不同型別會被過載。後面的引數的型別變化會被自動忽略。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/810/viewspace-2835195/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python中實現函式過載Python函式
- 在 Python 中實現函式過載Python函式
- PHP中實現函式過載PHP函式
- js實現函式過載JS函式
- 為什麼 Python 沒有函式過載?如何用裝飾器實現函式過載?Python函式
- Python 函式如何過載?Python函式
- 美麗的閉包,在js中實現函式過載JS函式
- 使用條件型別實現TypeScript中的函式過載型別TypeScript函式
- python函式過載是什麼?Python函式
- 關於python建構函式的過載Python函式
- JavaScript中的函式過載(Function overloading)JavaScript函式Function
- 118 C++中函式的過載C++函式
- TypeScript 函式過載TypeScript函式
- 函式模板過載函式
- C++ 函式過載,函式模板和函式模板過載,選擇哪一個?C++函式
- 學會TypeScript中函式過載寫法TypeScript函式
- 02-函式過載函式
- C++函式過載C++函式
- 過載的奧義之函式過載函式
- C++ 過載運算子和過載函式C++函式
- python中id()函式、zip()函式、map()函式、lamda函式Python函式
- Lua中呼叫ref和out修飾引數的函式/過載函式函式
- 在CPython中實現純Python函式的真正並行性Python函式並行
- python3程式碼中函式切割列表怎麼實現?Python函式
- 如何在PHP中實現鏈式方法呼叫PHP
- C++之函式過載C++函式
- Python - 函式實戰Python函式
- python函式每日一講 - filter函式過濾序列Python函式Filter
- js中實現單分派泛函式JS函式
- python(python中的super函式、)Python函式
- 如何實現JS中的過載JS
- 解析如何在Bash中編寫函式函式
- Python hasattr() 函式 // python中hasattr()、getattr()、setattr()函式的使用Python函式
- C++ 函式過載和模板C++函式
- 過載運算子、解構函式函式
- Python-split()函式用法及簡單實現Python函式
- Python基礎之openpyxl如何實現vlookup函式Python函式
- TypeScript中函式過載寫法,你在第幾層!TypeScript函式