请考虑以下简化示例:
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()时被调用一次。因此,全局变量的变化无效。有没有办法绕过这种行为?
答案 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
,因此您希望函数中应包含的任何行为都包含在其中。