전역 변수(Global Variable) 는 함수를 포함한 스크립트 전체에서 접근할 수 있는 변수입니다. 반면 지역 변수(Local Variable) 는 변수를 만든 함수 안에서만 접근할 수 있으며, 이 범위를 지역 범위(Local Scope) 라고 합니다.
# 전역 변수: 어디서든 접근 가능
x = 10
def print_x():
print(x) # 전역 변수 접근 가능
print_x() # 10
# 지역 변수: 함수 안에서만 접근 가능
def make_local():
y = 20 # 지역 변수
print(y)
make_local() # 20
# print(y) # NameError: y는 함수 밖에서 접근 불가
함수 안에서 전역 변수의 값을 변경하려면 global 키워드를 사용해야 합니다. global을 선언하지 않으면 파이썬은 함수 안에서 새로운 지역 변수를 만드는 것으로 처리합니다.
count = 0
def increment():
global count # 전역 변수 count를 사용하겠다고 선언
count += 1
increment()
increment()
print(count) # 2
전역 변수가 없는 상태에서 global을 사용하면 해당 변수가 새로운 전역 변수로 생성됩니다.
def create_global():
global new_var
new_var = "저는 전역 변수입니다"
create_global()
print(new_var) # 저는 전역 변수입니다
💡 네임스페이스(Namespace) 란 변수가 저장되는 공간입니다.
locals()함수로 현재 네임스페이스를 딕셔너리 형태로 확인할 수 있습니다.def show_namespace(): a = 1 b = 2 print(locals()) # {'a': 1, 'b': 2} show_namespace()
함수 안에 또 다른 함수가 있을 때, 바깥쪽 함수의 지역 변수에는 읽기 접근은 가능하지만 값을 변경하려면 nonlocal 키워드가 필요합니다.
def outer():
x = 10 # outer의 지역 변수
def inner():
nonlocal x # 바깥쪽 함수의 지역 변수를 사용
x += 1
print(x)
inner() # 11
print(x) # 11
outer()
nonlocal은 가장 가까운 바깥쪽 함수부터 변수를 찾습니다. 반면 global은 함수가 몇 단계로 중첩되어 있든 무조건 전역 변수를 가리킵니다.
| 키워드 | 대상 변수 | 탐색 방향 |
|---|---|---|
global | 전역 변수 | 무조건 전역 범위 |
nonlocal | 바깥쪽 함수의 지역 변수 | 가장 가까운 바깥쪽 함수부터 순서대로 |
클로저는 함수를 둘러싼 환경(바깥 함수의 지역 변수)을 기억하고 있다가, 나중에 함수를 호출할 때 그 환경을 다시 꺼내서 사용하는 함수입니다.
즉, return으로 반환되는 내부 함수가 참조하는 변수를 유지합니다.
바깥 함수가 종료된 이후에도 안쪽 함수가 바깥 함수의 변수를 계속 유지한다는 점이 핵심입니다.
def make_counter(start):
count = start # 바깥 함수의 지역 변수
def counter():
nonlocal count
count += 1
return count
return counter # 함수 자체를 반환
# make_counter가 종료되어도 count 값이 유지됨
counter_a = make_counter(0)
counter_b = make_counter(100)
print(counter_a()) # 1
print(counter_a()) # 2
print(counter_b()) # 101 ← counter_a와 독립적으로 동작
counter_a와 counter_b는 각각 독립된 환경을 유지합니다. 이처럼 클로저를 사용하면 프로그램의 흐름(상태)을 변수에 저장할 수 있습니다.
람다 표현식을 활용하면 클로저를 더 짧게 작성할 수 있습니다.
# def로 작성한 클로저
def make_adder(n):
def adder(x):
return x + n
return adder
# lambda로 작성한 클로저 — 훨씬 간결
def make_adder(n):
return lambda x: x + n
add_5 = make_adder(5)
add_10 = make_adder(10)
print(add_5(3)) # 8
print(add_10(3)) # 13
일반적으로 함수가 끝나면 내부 변수는 사라지는데, 내부 함수가 외부 변수를 참조하고 있으면 파이썬이 그 변수를 __closure__ 라는 공간에 보관한다.