首页 > 解决方案 > 用于检查任何函数注释类型的装饰器

问题描述

我想设计一个装饰器来检查任何函数注释类型,如果它具有相似的类型,则运行函数。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

另一件事是 annotations 是 dict 类型,我想要这样:

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       

标签: pythondecorator

解决方案


如果我正确理解这个想法,也许这段代码会帮助你:

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

装饰器检查参数类型,如果一切正常,则执行该函数,否则不执行任何操作。


推荐阅读