python中的顯式聲明類型參數(shù)使用方式
背景
筆者在用fastapi編寫ai rest service的時(shí)候發(fā)現(xiàn)官方的sample code函數(shù)參數(shù)都帶上了類型參數(shù). 以往筆者做python開發(fā)都不習(xí)慣帶類型參數(shù),認(rèn)為它是一門弱類型語言,不強(qiáng)制帶類型參數(shù)本質(zhì)上是為了開發(fā)效率.fastapi的官方文檔卻強(qiáng)調(diào)函數(shù)定義是要顯式帶參數(shù)類型,于是筆者就詳細(xì)研究了python顯式聲明參數(shù)類型的語法以及其帶來的好處.
python函數(shù)顯式聲明的類型匯總
顯示類型語法要分版本,筆者這里選擇3.10+版本,是現(xiàn)在主流的版本.
基本類型
str,int,float等python基本類型,最常見的顯式參數(shù)類型
def test1(a: int, b: str, c: float):
print("a is: " + str(a) + " b is: " + str(b) + " c is: " + str(c))
集合類型
list,dict,set,tuple. 集合類型都有內(nèi)部參數(shù)類型,這個(gè)等價(jià)于我們熟悉的java語言里面的泛型
def test2(a: list[str], b: set[float], c: dict[str, int], d: tuple[str, str]):
print(f"a is: {a} ")
print(f"b is ")
print(f"c is {c}")
print(f"d is wppm3vysvbp")
if __name__ == '__main__':
test2([1,2], {3,4}, {'a':1,'b':2}, ('a','b'))
這個(gè)也比較簡單,即便平時(shí)編碼不習(xí)慣顯示添加類型參數(shù),此類聲明語法也很直觀.
Optional and Union(python3.10版本之前)
Optional和Union需要詳細(xì)講解一下,這兩個(gè)類型在python 3,10版本之前使用比較多. 首先是union 表示當(dāng)前入?yún)⒖梢允?code>Union后面方括號指定的多類型中的一種,表示此參數(shù)可以支持多種類型,比如下例子:
from typing import Union
def test_union(a: Union[str, int]):
if isinstance(a, str):
print(f'a is str {a}')
elif isinstance(a, int):
print(f'a is int {str(a)}')
if __name__ == '__main__':
test_union('abc')
test_union(1)
輸出:
a is str abc a is int 1
表示參數(shù)a可以是str類型或者int類型
另一種情況,當(dāng)union只有兩個(gè)類型,且其中一個(gè)類型為None
def test_union2(a: Union[str, None]):
if a is None:
print("a is none")
else:
print(a.upper())
if __name__ == '__main__':
test_union2(a = None)
這種情況表明入?yún) 要么是str類型,要么可以為None,而且這種特殊情況下Union[str, None]就可以被Optional[str]替代.
from typing import Optional def test_optional(a: Optional[str]): print(a) if __name__ == '__main__': test_optional(a=None)
我們可以看作Optional是Union的一個(gè)特例.在3.10+版本后其實(shí)都可以不用從typing包引入Optional和Union兩種類型,在3.10+版本用一個(gè)|操作符就可以代替Union,比如下面這個(gè)例子:
def test_310(a: str|None): print(a) print(type(a)) if __name__ == '__main__': test_310(a='10') test_310(a=None) test_310(20)
可見在vscode里面這里即便聲明了類型參數(shù)可能是str,但是int類型也可以傳遞進(jìn)來.
來看下面一個(gè)有意思的case.
這里定義一個(gè)可以為None類型的參數(shù),調(diào)用的時(shí)候不賦值
def test_default(a: str|None): print(a) if __name__ == '__main__': test_default()
結(jié)果運(yùn)行報(bào)錯
test_default() missing 1 required positional argument: 'a'
注意語法a: str|None 以及 a: Optional[str] 或者 Union[str,None] 只是代表參數(shù)可以為None但是并不代表參數(shù)有默認(rèn)值
所以此類語法只是表示當(dāng)前參數(shù)類型可以是None,但并不表示存在None的默認(rèn)值.如果需要調(diào)用函數(shù)時(shí)不傳遞參數(shù),那么無論采用什么語法,在函數(shù)定義的時(shí)候還是需要給定默認(rèn)值None.
自定義類類型
類型參數(shù)還可以是自定義類,或者自定義類的集合類型
class A:
def __init__(self, val):
self.val = val
def test(self):
print(self.val)
def test_a(a: A):
a.test()
if __name__ == '__main__':
a = A('123')
test_a(a)
自定義類型作為集合中元素類型
def test_a_list(a: list[A]):
for item in a:
item.test()
if __name__ == '__main__':
a = [A('123'), A('234')]
test_a_list(a)
顯示聲明類型的好處
python是弱類型語言,本質(zhì)上是不需要去定義其變量類型或者參數(shù)的類型的.但是有些框架的源碼里面都有類型參數(shù)的聲明,不禁讓人思考這樣做帶來了什么好處.
看如下的例子:
無顯式聲明vscode沒有方法提示:

有顯式聲明vscode存在方法提示:

在vscode里面如果顯式聲明參數(shù)類型,當(dāng)?shù)粲么藚?shù)則可以提示此類型具備的方法,如果沒有顯式聲明參數(shù)類型則不會提示此類型具備的方法.
其次,顯示聲明參數(shù)類型是一種更規(guī)范的做法,它可以避免一些潛在的因?yàn)轭愋蜎]顯式聲明而帶來的編碼問題,這也能理解為什么fastapi的官方doc會提及到python的類型,且在官方的sample code里面都有顯示聲明參數(shù)類型.所以將此作為一個(gè)最佳實(shí)踐也不為過.
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用PyQt5+Pandas打造一個(gè)表格(Excel/CSV)讀取與處理工具
在日常辦公和數(shù)據(jù)分析中,我們經(jīng)常需要處理各種?Excel?和?CSV?文件,為了提高工作效率,今天我們將手把手教大家使用?PyQt5?和?Pandas?開發(fā)一款圖形化的表格讀取與處理工具,需要的朋友可以參考下2026-03-03
Python函數(shù)中的函數(shù)(閉包)用法實(shí)例
這篇文章主要介紹了Python函數(shù)中的函數(shù)(閉包)用法,結(jié)合實(shí)例形式分析了Python閉包的定義與使用技巧,需要的朋友可以參考下2016-03-03
PyQt6/PySide6中QTableView類的實(shí)現(xiàn)
本文主要介紹了PyQt6/PySide6中QTableView類的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
Python實(shí)現(xiàn)獲取命令行輸出結(jié)果的方法
這篇文章主要介紹了Python實(shí)現(xiàn)獲取命令行輸出結(jié)果的方法,涉及Python命令執(zhí)行及文件讀寫等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06

