我想设计一个装饰器来检查任何函数注释类型,如果它具有相似的类型,则运行函数。 python可以做这个事情吗? 如果Python可以,请帮助我!
def foo (a:int):
if foo.__annotations__.get('a') == type(a):
pass
def boo (b:str):
if boo.__annotations__.get('b') == type(b):
pass
另一件事是注释是字典类型,我想要这样:
from type import FunctionType
def check (f:FunctionType):
result = True
k = [k for k in f.__annotations__.keys()]
v = [v for v in f.__annotations__.values()]
for i in range(len(v)):
if v[i] != type(k[i]): #but we don't access to the type of k[i] out of th f function
result = False
return result
答案 0 :(得分:1)
类似这样的东西。
import inspect
import functools
def check(func):
msg = "Expected type {etype} for {para} got {got}"
para = inspect.signature(func).parameters
keys = tuple(para.keys())
@functools.wraps(func)
def wrapper(*args,**kwargs):
def do_check(anno,value,para):
if not isinstance(value, anno):
raise TypeError(msg.format(etype=anno,
para=para,
got=type(value)))
for i,value in enumerate(args):
anno = para[keys[i]].annotation
do_check(anno, value, keys[i])
for arg_name,value in kwargs.items():
anno = para[arg_name].annotation
do_check(anno, value, arg_name)
ret = func(*args,**kwargs)
if "return" in func.__annotations__:
anno = func.__annotations__["return"]
do_check(anno, ret, "return")
return ret
return wrapper
@check
def test(a:int,b:str) -> str:
return 'aaa'
@check
def test2(a:int,b:str) -> str:
return 123
答案 1 :(得分:1)
如果我正确理解了这个主意,也许这段代码可以为您提供帮助:
from types import FunctionType
def check(f: FunctionType):
def wrapper(*args, **kwargs):
result = True
# check args
keys = tuple(f.__annotations__.keys())
for ar in enumerate(args):
if not isinstance(ar[1], f.__annotations__.get(keys[ar[0]])):
result = False
break
if result:
# check kwargs
for k, v in kwargs.items():
if not isinstance(v, f.__annotations__.get(k)):
result = False
break
if result:
f(*args, **kwargs)
return wrapper
用法示例:
@check
def foo(a: str, b: int = None):
print(f"a = {a}")
print(f"b = {b}")
# Example 1: a=324, b=32:
foo(234, b=32)
# result: function not executed
# Example 2: a="abc", b="zzz":
foo("abc", b="zzz")
# result: function not executed
# Example 3: a="qwe", b= not set:
foo("qwe")
# result: function executed, output:
# a = qwe
# b = None
# Example 4: a="abc", b=99:
foo("abc", 99)
# result: function executed, output:
# a = abc
# b = 99
装饰器检查参数类型,如果一切正常,它将执行该函数,否则不执行任何操作。