带有参数的Python Decorator只调用一次

请考虑以下简化示例:

permitted = True
class is_allowed(object):
    def __init__(self, some_arg):
        # this is actually needed in the complete code
        self.some_arg = some_arg

    def __call__(self, f):
        if permitted == False:
            raise Exception("not authenticated to do that")
        def wrapped_f(*args, **kwargs):
            f(*args, **kwargs)
        return wrapped_f

@is_allowed("blah")
def print_hi():
    print("hi")

print_hi()
permitted = False
print_hi()

我想问题是装饰器只在定义函数print_hi()时被调用一次.因此,全局变量的变化无效.有没有办法绕过这种行为?

解决方法:

移动wrapped_f内部的检查

def __call__(self, f):
    def wrapped_f(*args, **kwargs):
        if not permitted:
            raise Exception("not authenticated to do that")
        f(*args, **kwargs)
    return wrapped_f

在wrapped_f之外,在创建函数时检查它.在内部,它成为新callable的主体的一部分,这意味着每次有呼叫时都会检查它.

您想要意识到将调用wrapped_f而不是print_hi,因此您希望应该包含在函数中的任何行为都在其中.

上一篇:如何在Java中实现包装装饰器?


下一篇:Python函数装饰器错误