0
点赞
收藏
分享

微信扫一扫

python--用装饰器做参数检查


1. 装饰器检测参数

import collections
import functools
import inspect


def para_check(func):
"""
函数参数检查装饰器,需要配合函数注解表达式(Function Annotations)使用
"""
msg = 'Argument {argument} must be {expected!r},but got {got!r},value {value!r}'

# 获取函数定义的参数
sig = inspect.signature(func)
parameters = sig.parameters # 参数有序字典
arg_keys = tuple(parameters.keys())

@functools.wraps(func)
def wrapper(*args, **kwargs):
CheckItem = collections.namedtuple('CheckItem', ('anno', 'arg_name', 'value'))
check_list = []

# collect args *args 传入的参数以及对应的函数参数注释
for i, value in enumerate(args):
arg_name = arg_keys[i]
anno = parameters[arg_name].annotation
check_list.append(CheckItem(anno, arg_name, value))

# collect kwargs **kwargs 传入的参数以及对应的函数参数注释
for arg_name, value in kwargs.items():
anno = parameters[arg_name].annotation
check_list.append(CheckItem(anno, arg_name, value))

# check type
for item in check_list:
if not isinstance(item.value, item.anno):
error = msg.format(expected=item.anno, argument=item.arg_name,
got=type(item.value), value=item.value)
raise TypeError(error)
return func(*args, **kwargs)
return wrapper


@para_check
def test(x: int, y: int):
return x + y


test('1', 2)

2. 执行结果

C:\Users\HuJun\PycharmProjects\pythonProject\venv\Scripts\python.exe "F:\PyCharm\PyCharm 2021.1.1\plugins\python\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 3899 --file C:/Users/HuJun/PycharmProjects/pythonProject/daily_tesy/decorate_check.py
Connected to pydev debugger (build 211.7142.13)
Traceback (most recent call last):
File "F:\PyCharm\PyCharm 2021.1.1\plugins\python\helpers\pydev\pydevd.py", line 1483, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "F:\PyCharm\PyCharm 2021.1.1\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/HuJun/PycharmProjects/pythonProject/daily_tesy/decorate_check.py", line 48, in <module>
test('1', 2)
File "C:/Users/HuJun/PycharmProjects/pythonProject/daily_tesy/decorate_check.py", line 38, in wrapper
raise TypeError(error)
TypeError: Argument x must be <class 'int'>,but got <class 'str'>,value '1'
python-BaseException

Process finished with exit code 1


举报

相关推荐

0 条评论