import functools,inspect
def typed(fn):
@functools.wraps(fn)
def wrap(*args,**kwargs):
# 如何检查
# 获得被装饰函数的所有参数,但这是一个对象,不是具体的值
params=inspect.signature(fn).parameters
# 检查关键字参数
for k,v in kwargs.items():
# items()返回键、值
param = params[k]
# 如果参数有类型注解,并且参数的值和键是不一致的,报错
if param.annotation != inspect._empty and not isinstance(v,params[k].annotation):
raise TypeError(f"parameter {k} require {params[k].annotation},but {type(arg)}")
# 检查位置参数
for i,arg in enumerate(args):
param = list(params.values())[i]
if param.annotation != inspect._empty and not isinstance(arg,param.annotation):
raise TypeError(f"parameter {param.name} required {param.annotation},but {type(arg)}")
return fn(*args,**kwargs)
return wrap
@typed
def add(x:int,y:int)->int:
return x+y
测试:
add('a',2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-39-f579e865fd3c> in <module>
----> 1 add('a',2)
<ipython-input-38-820b615a4365> in wrap(*args, **kwargs)
17 param = list(params.values())[i]
18 if param.annotation != inspect._empty and not isinstance(arg,param.annotation):
---> 19 raise TypeError(f"parameter {param.name} required {param.annotation},but {type(arg)}")
20 return fn(*args,**kwargs)
21 return wrap
TypeError: parameter x required <class 'int'>,but <class 'str'>
add(y=3,s='s')
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-41-272731de6622> in <module>
----> 1 add(y=3,s='s')
<ipython-input-38-820b615a4365> in wrap(*args, **kwargs)
9 for k,v in kwargs.items():
10 # items()返回键、值
---> 11 param = params[k]
12 # 如果参数有类型注解,并且参数的值和键是不一致的,报错
13 if param.annotation != inspect._empty and not isinstance(v,params[k].annotation):
KeyError: 's'
add(1,2)
3