Closure
자신을 둘러싼 scope의 상태 값을 기억하는 함수로, 클로저는 다음의 세 가지 조건을 만족해야 한다.
- 해당 함수는 어떤 함수 내에 중첩된 함수여야 한다.
- 해당 함수는 자신을 둘러싼 함수 내의 상태 값을 참조해야 한다.
- 해당 함수를 둘러싼 함수는 내부의 함수의 반환해야 한다.
💡 각 조건에 대한 배경 지식은 아래 글을 참고할 수 있다.
예시를 통해 알아보자.
예시
지역 변수 a, b를 샤용하여 결괏값을 계산하는 함수 mul_add를 반환하는 함수 calc가 있다고 하자.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b
return mul_add
calc 함수를 변수 c에 저장한 후 실행해보자.
c = calc()
print(c(1))
print(c(5))
c에는 calc의 반환값인 mul_add가 저장되는데, 이때 외부 함수인 calc의 역할이 끝나며 관련 변수 등이 메모리에서 사라질 거라고 생각할 수 있다. 하지만 실제로 c를 호출해보면 mul_add를 둘러싼 calc의 지역 변수를 사용해 연산 결과를 반환하는 것을 확인할 수 있다.
즉, 이렇게 함수를 둘러싼 환경을 유지하다 함수를 호출할 때 사용하는 함수를 클로저라고 한다.
클로저는 지역 변수와 코드를 묶어서 사용하고 싶을 때 활용할 수 있다.
특징
1. 클로저는 원 함수가 메모리에서 삭제되도, 참조한 자신을 둘러싼 함수 scope의 상태 값을 유지한다.
위의 예시 함수 calc를 del 함수로 삭제한 후, c를 통해 클로저를 호출해보았다.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b
return mul_add
c = calc()
print(c(1))
print(c(5))
del(calc)
print(c(5))
클로저는 원 함수에 어떤 변화가 발생해도 자신의 scope을 유지한다.
2. 클로저는 자신을 둘러싸고 있는 변수에 접근할 수 있다.
Python 3 기준으로, 클로저는 자신을 둘러싼 함수 scope에서 참조하는 변수를 저장하는 변수 __closure__를 기본적으로 가진다. __closure__ 변수는 튜플이며, 각 원소의 cell_contents는 참조 변수의 값을 저장하고 있다.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b
return mul_add
c = calc()
for i in c.__closure__:
print(i.cell_contents)
참고 문서
https://shoark7.github.io/programming/python/closure-in-python#3
https://dojang.io/mod/page/view.php?id=2366