天天看點

檢查函數傳入參數的合法性

python是一門動态語言,是以在調用函數的時候,可以傳入任何類型的資料,而他又是一門強類型語言,當傳入的參數不合法時,便會在内部報錯。

為了減少這一錯誤的發生,python從3.5開始引入了函數注解,如下所示:

def fn(x:int, y:int):
    pass
           

配合inspect子產品,可以有效的檢查傳入函數是否合法

首先,通過sig=inpect.signature(fn),可以擷取到fn函數的參數,然後通過sig.parameters得到一個參數的OrderedDict,當調用函數fn時,通過擷取函數調用時傳入的參數,來判斷是否符合有序字典中相應的參數類型。

在此,可以把該方法包裝成一個check裝飾器,具體代碼實作大緻如下:

import inspect,functools
def check(fn):
	@functools.wraps(fn)  #把被包裝函數的屬性賦給wrapper
	def wrapper(*args,**kwargs):
		sig = inspect.signature(fn)  #擷取函數參數類型
		params = sig.parameters  #有序字典
		values = list(params.values())
		for i,v in enumerate(args):   #擷取函數調用時的值
			if values[i].annotation is inspect._empty or isinstance(v, values[i].annotation):  #如果函數注解為空或者輸入的值符合函數注解時pass,否則提示參數錯誤
				pass
			else:
				print('wrong param')
				return
		for k, v in kwargs.items():
			if params[k].annotation is inspect._empty or isinstance(v, params[k].annotation):
				pass
			else:
				print('wrong param')
				return
		x = fn(*args,**kwargs)
		return x
	return wrapper