변수의 범위(scope)는 변수가 사용 가능한 컨텍스트입니다. Python에는 LEGB 원칙에 따라 기억할 수 있는 4가지 기본 범위가 있습니다:
global 키워드는 함수 내부에서 글로벌 수준에 선언된 변수를 변경할 수 있게 해줍니다.
def foo(): global my_var my_var = 10 # 글로벌 변수를 변경합니다.
함수 내부에서 global 없이 변수를 사용하면 해당 변수는 로컬로 간주되며 외부의 동일한 이름이 있어도 로컬 변수가 됩니다.
"다음 코드는 무엇을 출력합니까?"
x = 10 def func(): x = 20 func() print(x)
답변:
10을 출력합니다. 이는 함수 내부에서 새로운 로컬 변수 x가 생성되고, 글로벌 변수는 변경되지 않기 때문입니다.
이야기
봇의 명령 처리기에서 글로벌 카운터를 저장하려 했지만 global을 잊었습니다:
counter = 0 def increment(): counter += 1 # UnboundLocalError: 지역 변수 'counter'가 할당 전에 참조됨
오류는 인터프리터가 counter를 로컬 변수로 간주했기 때문입니다 (함수 내에서 할당이 발생하므로), 글로벌 변수가 아닙니다.
이야기
중첩 함수에서 nonlocal 키워드 없이 숨겨진 변수가 로컬 범위를 생성한다는 것을 잊었습니다:
def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x는 inner에서 로컬로 간주됩니다.
올바르게:
def outer(): x = 0 def inner(): nonlocal x x += 1
이야기
한 줄로 작성하려 했습니다:
x = 5 y = (lambda: (x := x + 1))() # Python < 3.8에서는 SyntaxError, 아니면 나중에 UnboundLocalError
표현식과 lambda에 대한 범위의 차이를 잊었습니다. 모든 구조가 lambda 내부에서 할당을 지원하는 것은 아니며, Python 버전에 따라 다릅니다.