Python

[Python] Closure

비번변경 2022. 10. 4. 00:15

Closure

자신을 둘러싼 scope의 상태 값을 기억하는 함수로, 클로저는 다음의 세 가지 조건을 만족해야 한다.

 

  1. 해당 함수는 어떤 함수 내에 중첩된 함수여야 한다.
  2. 해당 함수는 자신을 둘러싼 함수 내의 상태 값을 참조해야 한다.
  3. 해당 함수를 둘러싼 함수는 내부의 함수의 반환해야 한다.
💡 각 조건에 대한 배경 지식은 아래 글을 참고할 수 있다.

2022.10.01 - [Python] 전역/지역 변수와 범위

2022.11.03 - [Python] 중첩 함수

2021.11.23 - [Python] 변수에 함수 저장

 

예시를 통해 알아보자.

 

 

예시

지역 변수 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))

closure 실행 결과

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)

__closure__

 

 

참고 문서

https://shoark7.github.io/programming/python/closure-in-python#3

https://dojang.io/mod/page/view.php?id=2366