Python3使用装饰器实现参数类型检查

发布时间 2023-06-19 16:13:12作者: 韩志超
from functools import wraps


def merge_args(varnames: tuple, args: tuple, kwargs: dict) -> dict:
    """
    融合参数-将args参数都转为kwargs参数
    :param varnames: 变量名列表
    :param args: args参数
    :param kwargs: kwargs参数
    :return:
    """
    merged_kwargs = kwargs
    if args:
        merged_kwargs.update(dict(zip(varnames, args)))
    return merged_kwargs


def check_args(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        types_hint = func.__annotations__  # dict or None
        if types_hint:
            merged_kwargs = merge_args(func.__code__.co_varnames, args, kwargs)
            for key, value in merged_kwargs.items():
                if key in types_hint and not isinstance(value, types_hint[key]):
                    raise TypeError(f'参数 "{key}" 不符合注释类型 {types_hint[key]}')

    return wrapper


@check_args
def add(a: int, b: int):
    return a + b


if __name__ == '__main__':
    print(add(1.0, 2))

运行结果如下:

Traceback (most recent call last):
  File "/Users/superhin/Projects/试验/d01/18_装饰器_参数检查.py", line 37, in <module>
    print(add(1.0, 2))
  File "/Users/superhin/Projects/试验/d01/18_装饰器_参数检查.py", line 26, in wrapper
    raise TypeError(f'参数 "{key}" 不符合注释类型 {types_hint[key]}')
TypeError: 参数 "a" 不符合注释类型 <class 'int'>