携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
0 环境
- 编辑器:pycharm或者vscode
- 系统版本:windows10
- python版本:3.9.6
1 关键字判断
之前自写的检查函数,虽然实现了可变参数的校验,但是有时候会传入关键字,这时候怎么办呢,需要对关键字进行处理是吧,如下代码:
都知道了这里的params变量是个字典,我们在越过位置参数的判断代码,直达关键字检查这个位置,先是一个for循环,kwargs.items(),为什么可以这么用,因为是kwargs --> 字典,可以用items获取它的key, value,就是我们传入count(y=4, x=2)里的参数嘛,下面的value和该值的键下的类型注解对比,不一致,抛出异常和具体的错误信息。再次补充说明,@functools.wraps,一般都要加上,为了避免文档和函数名出现异常。inspect.signature(fn).parameters目的是要读取到被装饰器函数的所有参数(目的是类型注解),它是一个对象(返回的是整体)。不管是位置参数还是关键字,目的还是一致的,就是它的具体值和对应的函数参数的注解类型是否一致。还有一种情况就是该值对应的键没有注解类型,params[key].annotation != inspect._empty就是帮我们判断每个参数是否存在注解类型。
import functools
import typing
import inspect
def typed(fn):
@functools.wraps(fn)
def wrap(*args, **kwargs):
# 检查
params = inspect.signature(fn).parameters
# 位置参数检查
for index, arg in enumerate(args):
print(index, arg)
print(params)
print(type(params.values()), params.values())
param = list(params.values())[index]
if not isinstance(arg, param.annotation):
raise TypeError(f"parameter {param.name} required {param.annotation}, but {type(arg)}")
# 关键字检查
for key, value in kwargs.items():
# kwargs里面的value是否等于params[key]里的注解
if params[key].annotation != inspect._empty and not isinstance(value, params[key].annotation):
raise TypeError(f"paramter {key} require {params[key].annotation}, but {type(key)}")
return fn(*args, **kwargs)
return wrap
@typed
def count(x: int, y: int) -> int:
return x + y
if __name__ == '__main__':
# count(1,2)
count(y=4, x=2)
# count(y=4, x="1")
2 总结
inspect库是不是很强大,很方便我们的开发,比如一下权限校验等方面。