python 装饰器可以用来改变函数返回的函数的行为吗?

Can python decorators be used to change behavior of a function returned by a function?

我有函数,return 验证器函数,简单示例:

def check_len(n):
    return lambda s: len(s) == n

是否可以添加一个装饰器,打印出一条消息,以防检查结果为 false? 像这样:

@log_false_but_how
def check_len(n):
    return lambda s: len(s) == n

check_one = check_len(1)
print(check_one('a')) # returns True
print(check_one('abc')) # return False

预期输出:

True
validator evaluated to False
False

我试过创建注释,但只能使用它访问函数创建。 一种方法是像这样定义函数:

def log_false(fn):
    def inner(*args):
        res = fn(*args)
        if not res:
            print("validation failed for {}".format(fn.__name__))
        return res
    return inner


@log_false
def check_one(s):
    return check_len(1)(s)

但是这样我们就失去了验证函数的动态创建。

您在错误的地方进行验证。 check_len 是一个函数工厂,所以 res 不是布尔值——它是一个函数。您的 @log_false 装饰器必须在 check_len 返回的每个 lambda 周围包装一个验证器函数。基本上你需要写一个装饰器来装饰返回的函数。

def log_false(validator_factory):
    # We'll create a wrapper for the validator_factory
    # that applies a decorator to each function returned
    # by the factory

    def check_result(validator):
        @functools.wraps(validator)
        def wrapper(*args, **kwargs):
            result = validator(*args, **kwargs)
            if not result:
                name = validator_factory.__name__
                print('validation failed for {}'.format(name))
            return result
        return wrapper

    @functools.wraps(validator_factory)
    def wrapper(*args, **kwargs):
        validator = validator_factory(*args, **kwargs)
        return check_result(validator)
    return wrapper

结果:

@log_false
def check_len(n):
    return lambda s: len(s) == n

check_one = check_len(1)
print(check_one('a')) # prints nothing
print(check_one('abc')) # prints "validation failed for check_len"