nonlocal이 필요한 경우와 필요 없는 경우
파이썬에서 내부 함수가 외부 변수를 다룰 때, 두 가지 경우가 있습니다:
1. 변경(뮤테이션, mutation)만 하는 경우 → nonlocal 불필요
def closure_ex1():
series = [] # 리스트 (가변 객체)
def averager(v):
series.append(v) # 리스트 내부 수정
return sum(series) / len(series)
return averager
avg = closure_ex1()
print(avg(10)) # 10.0
print(avg(20)) # 15.0
- series.append(v)는 리스트 내부를 수정하는 동작(뮤테이션)
- series 자체를 새로 대입하지 않으므로, 파이썬은 그냥 외부 변수를 참조
- nonlocal 필요 없음
2. 재할당(reassignment) 하는 경우 → nonlocal 필요
def closure_ex2():
cnt = 0 # 정수 (불변 객체)
total = 0
def averager(v):
nonlocal cnt, total # 외부 변수 사용을 명시
cnt += 1 # cnt = cnt + 1 (재할당 발생)
total += v # total = total + v (재할당 발생)
return total / cnt
return averager
avg = closure_ex2()
print(avg(10)) # 10.0
print(avg(30)) # 20.0
- cnt += 1은 사실상 cnt = cnt + 1 → 변수에 새 값을 대입하는 것
- 이때 nonlocal을 쓰지 않으면 파이썬은 cnt를 내부 함수의 지역 변수로 인식해버림
- 아직 초기화되지 않은 지역 변수를 읽으려 하니 UnboundLocalError 발생
- nonlocal로 “바깥 변수 쓰겠다” 명시해야 함
정리하면
- 클로저는 외부 변수를 기억한다.
- 하지만 내부 함수에서 그 변수를 **재할당하려면 반드시 nonlocal**을 사용해야 한다.
- 반대로 가변 객체의 내용만 수정한다면 nonlocal 없이도 동작한다.
'파이썬 > 기초 프로그래밍' 카테고리의 다른 글
| 파이썬 이터레이터 예제: WordSplitIter (1) | 2025.09.08 |
|---|---|
| 파이썬 데코레이터와 클로저 정리 (0) | 2025.09.08 |
| 파이썬 클로저(Closure)와 nonlocal 키워드 (0) | 2025.09.08 |
| 파이썬 클로저(Closure) 간단 이해 + 내부 구조 들여다보기 (0) | 2025.09.08 |
| __call__ 재정의: 클래스도 함수처럼 사용하기 (1) | 2025.09.07 |