에듀테크 프로젝트 대시보드
스코프 · 클로저
이름을 찾는 순서: Local → Enclosing → Global → Built-in.
x = "global"
def outer():
x = "enclosing"
def inner():
# x 를 안 만들었으므로 바깥에서 찾음
print(x) # => 'enclosing'
inner()
len # built-in (아무 데도 정의 안 했지만 찾음)count = 0
def increment():
count += 1 # UnboundLocalError!
# 대입이 있으면 count 를 지역변수로 간주 → 오른쪽 count 가 미정의
def increment():
global count # "바깥 count 를 쓰겠다"
count += 1def make_counter():
count = 0
def tick():
nonlocal count # enclosing 스코프의 count
count += 1
return count
return tick
c = make_counter()
c(); c(); c() # => 1, 2, 3def multiplier(factor):
def multiply(n):
return n * factor # factor 를 "기억"
return multiply
double = multiplier(2)
triple = multiplier(3)
double(10) # => 20
triple(10) # => 30
double.__closure__[0].cell_contents # => 2 (갇힌 값)# 흔한 버그: 모든 함수가 마지막 i 를 참조
funcs = [lambda: i for i in range(3)]
[f() for f in funcs] # => [2, 2, 2] (기대: 0,1,2)
# 해결 1: 기본 인자로 현재 값 고정
funcs = [lambda i=i: i for i in range(3)] # => [0, 1, 2]
# 해결 2: 팩토리 함수
def make(i):
return lambda: i
funcs = [make(i) for i in range(3)]def f():
a = 1
print(locals()) # {'a': 1}
print(globals().keys()) # 모듈 전역
x = 10
def g():
exec("x = 99") # locals 수정은 반영 안 될 수 있음 — 사용 자제