Python中的函數(shù)參數(shù)類(lèi)型檢查
Python函數(shù)參數(shù)類(lèi)型檢查
有一個(gè)很經(jīng)典的笑話(huà):
三個(gè)月之前,只有我和上帝知道這代碼是干什么的。
現(xiàn)在,只有上帝知道了。
在Python中,不知道函數(shù)參數(shù)類(lèi)型是一個(gè)很正常的事情,特別是在一個(gè)大項(xiàng)目里。
我見(jiàn)過(guò)有些項(xiàng)目里,每一個(gè)函數(shù)體的前十幾行都在檢查參數(shù)類(lèi)型,這實(shí)在是太麻煩了。而且一旦參數(shù)有改動(dòng),這部分也需要改動(dòng)。
下面我們用裝飾器來(lái)實(shí)現(xiàn)
函數(shù)參數(shù)的強(qiáng)制類(lèi)型檢查。
首先,這個(gè)裝飾器,要接受類(lèi)型參數(shù),和指定函數(shù)參數(shù)的類(lèi)型參數(shù)。也就是一個(gè)list和一個(gè)dict
from functools import wraps def typeassert(*type_args, **type_kwargs): ? ? def decorate(func): ? ? ? ? @wraps(func) ? ? ? ? def wrapper(*args, **kwargs): ? ? ? ? ? ? return func(*args, **kwargs) ? ? ? ? return wrapper ? ? return decorate
@wraps(func)的作用請(qǐng)看我的另一篇
那么,接下來(lái),在裝飾器中,我們需要獲取函數(shù)參數(shù)列表,并且要和類(lèi)型參數(shù)表映射。
這要借助Python的一個(gè)標(biāo)準(zhǔn)庫(kù)——inspect 這個(gè)庫(kù)一般用于Python代碼調(diào)試
from inspect import signature from functools import wraps def typeassert(*type_args, **type_kwargs): ? ? def decorate(func): ? ? ? ? sig = signature(func) ? ? ? ? bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments ? ? ? ? @wraps(func) ? ? ? ? def wrapper(*args, **kwargs): ? ? ? ? ? ? return func(*args, **kwargs) ? ? ? ? return wrapper ? ? return decorate
上面的代碼中,我們使用inspect中的signature方法獲取了func的Signature對(duì)象,然后使用bind_partial方法創(chuàng)建了(*type_args, **type_kwargs)到func參數(shù)的映射(也就是一個(gè)字典)。
接下來(lái)就簡(jiǎn)單了,我們只需要再獲取(*args, **kwargs)的類(lèi)型,使用isintance函數(shù)進(jìn)行比較就好。
from inspect import signature from functools import wraps def typeassert(*type_args, **type_kwargs): ? ? def decorate(func): ? ? ? ? sig = signature(func) ? ? ? ? bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments ? ? ? ? @wraps(func) ? ? ? ? def wrapper(*args, **kwargs): ? ? ? ? ? ? bound_values = sig.bind(*args, **kwargs) ? ? ? ? ? ? for name, value in bound_values.arguments.items(): ? ? ? ? ? ? ? ? if name in bound_types: ? ? ? ? ? ? ? ? ? ? if not isinstance(value, bound_types[name]): ? ? ? ? ? ? ? ? ? ? ? ? raise TypeError('Argument {} must be {}'.format(name, bound_types[name])) ? ? ? ? ? ? return func(*args, **kwargs) ? ? ? ? return wrapper ? ? return decorate
運(yùn)行如下代碼
@typeassert(int, int) def add(x, y): ? ? return x+y print(add("u", 2))
能看到報(bào)錯(cuò)如下
Traceback (most recent call last):
File "c:\Users\Chen\Desktop\typeassert.py", line 32, in <module>
print(add("u", 2))
File "c:\Users\Chen\Desktop\typeassert.py", line 22, in wrapper
'Argument {} must be {}'.format(name, bound_types[name])
TypeError: Argument x must be <class 'int'>
很貼心的提醒了我們哪一個(gè)參數(shù)應(yīng)該是什么類(lèi)型。
你甚至可以自己改動(dòng)這個(gè)裝飾器,讓它還能告訴你傳進(jìn)去了什么錯(cuò)誤參數(shù)(特別是寫(xiě)爬蟲(chóng)的時(shí)候,參數(shù)很難掌握,一旦報(bào)錯(cuò),還得重跑一遍才知道為什么。)
你也可以指定某一個(gè)參數(shù)的類(lèi)型,譬如
@typeassert(int, z=str) def display(x, y, z): ? ? print(x, y, z)
這時(shí)你會(huì)發(fā)現(xiàn),y的類(lèi)型就像原生的Python函數(shù)一樣,什么都行。而x必須是int,z必須是str。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Python中實(shí)現(xiàn)參數(shù)類(lèi)型檢查的簡(jiǎn)單方法
- python通過(guò)裝飾器檢查函數(shù)參數(shù)數(shù)據(jù)類(lèi)型的方法
- Python 限定函數(shù)參數(shù)的類(lèi)型及默認(rèn)值方式
- Python參數(shù)類(lèi)型以及常見(jiàn)的坑詳解
- python 判斷參數(shù)為Nonetype類(lèi)型或空的實(shí)例
- Python函數(shù)參數(shù)類(lèi)型*、**的區(qū)別
- Python?調(diào)用函數(shù)時(shí)檢查參數(shù)的類(lèi)型是否合規(guī)的實(shí)現(xiàn)代碼
相關(guān)文章
tkinter如何實(shí)現(xiàn)label超鏈接調(diào)用瀏覽器打開(kāi)網(wǎng)址
這篇文章主要介紹了tkinter如何實(shí)現(xiàn)label超鏈接調(diào)用瀏覽器打開(kāi)網(wǎng)址問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01python通過(guò)實(shí)例講解反射機(jī)制
這篇文章主要介紹了python通過(guò)實(shí)例講解反射機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10anaconda虛擬環(huán)境python?sklearn庫(kù)的安裝過(guò)程
Anaconda是專(zhuān)注于數(shù)據(jù)分析的Python發(fā)行版本,包含了conda、Python等190多個(gè)科學(xué)包及其依賴(lài)項(xiàng),這篇文章主要給大家介紹了關(guān)于anaconda虛擬環(huán)境python?sklearn庫(kù)的安裝過(guò)程,需要的朋友可以參考下2023-11-11淺談flask中的before_request與after_request
這篇文章主要介紹了淺談flask中的before_request與after_request,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Python?PyJWT庫(kù)簡(jiǎn)化JSON?Web?Token的生成與驗(yàn)證
PyJWT庫(kù)為Python開(kāi)發(fā)者提供了簡(jiǎn)便的生成和驗(yàn)證JWT的工具,本文將深入介紹PyJWT庫(kù)的核心概念、功能以及實(shí)際應(yīng)用,通過(guò)豐富的示例代碼,幫助大家更全面地了解和應(yīng)用這一強(qiáng)大的JWT庫(kù)2023-12-12Pytorch深度學(xué)習(xí)之實(shí)現(xiàn)病蟲(chóng)害圖像分類(lèi)
PyTorch是一個(gè)開(kāi)源的Python機(jī)器學(xué)習(xí)庫(kù),基于Torch,用于自然語(yǔ)言處理等應(yīng)用程序。它具有強(qiáng)大的GPU加速的張量計(jì)算和自動(dòng)求導(dǎo)系統(tǒng)的深度神經(jīng)網(wǎng)絡(luò)。本文將介紹如何通過(guò)PyTorch實(shí)現(xiàn)病蟲(chóng)害圖像分類(lèi),感興趣的可以學(xué)習(xí)一下2021-12-12