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

时间:2014-12-20 00:58:46

标签: python python-3.x decorator python-decorators

请考虑以下简化示例:

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()时被调用一次。因此,全局变量的变化无效。有没有办法绕过这种行为?

1 个答案:

答案 0 :(得分:5)

将检查移到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,因此您希望函数中应包含的任何行为都包含在其中。