2014-12-20 19 views
3

请考虑以下简单的例子:Python的装饰与参数只调用一次

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()定义为当装饰只调用一次。因为全局变量的变化没有效果。有什么办法可以避免这种行为?

回答

5

移动wrapped_fwrapped_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将被调用而不是print_hi,所以你想要任何应该包含在函数中的行为。

+0

很酷,谢谢。接受在10分钟;) – Stefan

+1

为OP的好处,你应该真的这样做:'如果允许== False'像这样:'如果不允许' – Anentropic

+0

@Antropic yes一开始没有接受,我已经更新 –