qq_46601351 2022-07-23 14:55 采纳率: 50%
浏览 42
已结题

用python装饰器完成一个参数检查器

用python装饰器完成一个参数检查器,若参数是整形 数字在0-10之间,若是字符串 长度在8-16之间 若是数组list 则要求类型都是字符串 其他类型默认参数不能为空。如果校验不通过,则抛异常,通过则继续执行

  • 写回答

2条回答 默认 最新

  • m0_72929209 2022-07-23 16:07
    关注

    import collections
    import functools
    import inspect

    def para_check(func):
    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)

    1. 执行结果
      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
      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

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月23日
  • 创建了问题 7月23日