데코레이터를 작성하고 있는데 어디서든 그것들을 재정의하려고하면 내부 함수에 변수 범위가있는 이상한 동작이 있습니다.
def decorate_me(a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
return func(*args, **kwargs)
return wrapper
return decorator
예상대로 작동하며 문제가 없습니다. 그러나 a_variable이 마지막에 재정의되면 :
def decorate_me(self, a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
# --- --- --- --- --- ---
# THIS LINE RIGHT HERE
# --- --- --- --- --- ---
a_variable = not a_variable
return func(*args, **kwargs)
return wrapper
return decorator
이로 인해 오류가 발생합니다.
File "...", line 41, in wrapper
print(a_variable)
UnboundLocalError: local variable 'a_variable' referenced before assignment
변수를 재정의하면 어떻게 재정의보다 몇 줄 위의 명령문에서 바인딩이 해제됩니까? 여기서 규칙은 무엇이며 어떻게 피할 수 있습니까?
이것은 Python FAQ 에서 대답 하고 Eli Bendersky가 여기에서 설명 합니다 . 'Python UnboundLocalError'를 검색 할 때 가장 먼저 표시되는 것입니다.
Python의 FAQ에서 :
이는 범위의 변수에 할당 할 때 해당 변수가 해당 범위에 대해 로컬이되고 외부 범위에서 비슷한 이름의 변수를 숨기기 때문입니다. foo의 마지막 문은 x에 새 값을 할당하므로 컴파일러는이를 지역 변수로 인식합니다. 결과적으로 이전 print (x)가 초기화되지 않은 지역 변수를 인쇄하려고 시도하고 오류가 발생합니다.
간단히 변수를 재정의하면 범위가 재정의되므로 외부 범위에서 변수가 제거됩니다.
이에 대한 해결책은 global
또는 nonlocal
키워드 를 사용하는 것 입니다. 문제의 예에서 global
작동하지 않음 ( a_variable
)은 전역 적이 지 않지만 nonlocal
작동합니다. 명시 적으로 내부 함수에 외부 범위의 변수를 사용하도록 지시합니다.
Eli Bendersky의 설명은 왜 이런 일이 발생하는지에 대해 더 자세히 설명하며 읽을 가치가 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다