2014-12-20 1 views
3

는 다음과 같은 간단한 예를 고려하시기 바랍니다 일단라는 인수 파이썬 데코레이터 : 나는 문제가 함수 print_hi()가 정의 될 때 데코레이터는 한 번만 호출되는 것 같다

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() 

. 이 때문에 전역 변수의 변경은 아무 효과가 없습니다. 이 행동을 포기할 방법이 있습니까?

답변

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 

외부의 내부 검사를 이동

, 이는 함수의 생성에서 체크된다. 내부에서는 새로운 호출 가능 프로그램의 본문에 포함되며 호출이있을 때마다 검사됩니다.

print_hi 대신 wrapped_f이 호출되기를 원하기 때문에 함수에 포함되어야하는 모든 동작이 그 내부로 들어가기를 원합니다.

+0

멋진 답변입니다. 10 분 안에 받아 들일 수 있습니다.) – Stefan

+1

OP의 이익을 위해, 당신은 정말로 이것을해야합니다 :'허용 된 경우 == 거짓'같은 경우 :'허용되지 않을 경우' – Anentropic

+0

@Anentropic 예 처음에 그걸 알아 채지 못했습니다. –