2014-12-20 3 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_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 будет вызываться wrapped_f, поэтому вы хотите, чтобы какое-либо поведение включалось в функцию, чтобы войти в нее.

+0

прохладный, спасибо. Принимая в 10мин;) – Stefan

+1

в пользу OP, вы действительно должны это сделать: 'if allowed == False', как это:' if not allowed' – Anentropic

+0

@ Anentropic да не поймал, что сначала, я обновил –

Смежные вопросы