def A():
x = 10 # A의 지역 변수 x
def B():
x = 20 # x에 20 할당
B()
print(x) # A의 지역 변수 x 출력
A()
# 실행 결과
10
함수 B에서 x를 변경해도 print()는 속해있는 함수 A에서 x값을 가져온다.
현재 함수의 바깥쪽에 있는 지역 변수의 값을 변경하려면 nonlocal 키워드를 사용해야 한다. 다음과 같이 함수 안에서 nonlocal에 지역 변수의 이름을 지정해준다.
nonlocal 지역변수
function_nonlocal_keyword.py
def A():
x = 10 # A의 지역 변수 x
def B():
nonlocal x # 현재 함수의 바깥쪽에 있는 지역 변수 사용
x = 20 # A의 지역 변수 x에 20 할당
B()
print(x) # A의 지역 변수 x 출력
A()
# 실행 결과
20
nonlocal은 현재 함수의 바깥쪽에 있는 지역 변수를 찾을 때 가장 가까운 함수부터 먼저 찾는다.
함수가 몇 단계든 상관없이 global 키워드를 사용하면 무조건 전역 변수를 사용하게 된다.
function_in_function_global_keyword.py
x = 1
def A():
x = 10
def B():
x = 20
def C():
global x
x = x + 30
print(x)
C()
B()
A()
# 실행 결과
31
클로저란 함수를 둘러싼 환경(지역 변수, 코드 등)을 계속 유지하다가, 함수를 호출할 때 다시 꺼내서 사용하는 함수를 말한다.
함수 바깥쪽에 있는 지역 변수 a, b를 사용하여 a * x + b를 계산하는 함수 mul_add를 만든 뒤에 함수 mul_add 자체를 반환하는 함수다.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b # 함수 바깥쪽에 있는 지역 변수 a, b를 사용하여 계산
return mul_add # mul_add 함수를 반환
c = calc()
print(c(1), c(2), c(3), c(4), c(5))
# 실행 결과
8 11 14 17 20
클로저는 지역 변수와 코드를 묶어서 사용하고 싶을 때 활용한다. 클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용한다.
위와 동일한 클로저를 람다로 만들었다.
def calc():
a = 3
b = 5
return lambda x: a * x + b # 람다 표현식을 반환
c = calc()
print(c(1), c(2), c(3), c(4), c(5))
nonlocal을 사용한다.
# a * x + b의 결과를 함수 calc의 지역 변수 total에 누적한다.
def calc():
a = 3
b = 5
total = 0
def mul_add(x):
nonlocal total
total = total + a * x + b
print(total)
return mul_add
c = calc()
c(1)
c(2)
c(3)
# 실행 결과
8
19
33
💡 출처, 강의