Skip to content

Instantly share code, notes, and snippets.

@nattybear
Last active October 24, 2022 20:04
Show Gist options
  • Save nattybear/5e7184701247f0fdf5280b5e13b7772b to your computer and use it in GitHub Desktop.
Save nattybear/5e7184701247f0fdf5280b5e13b7772b to your computer and use it in GitHub Desktop.
파이썬 클로저

함수 안에 함수

파이썬에서는 아래와 같이 함수 안에 함수를 선언할 수 있습니다.

def outside():
  def inside():
    pass

그런데 이때 함수 inside에서는 함수 outside 에 있는 변수에도 접근할 수 있습니다.

def outside():
  n = 1
  def inside():
    print(n)  # 1

이렇게 함수 inside가 함수 outside에 있는 변수에 접근할 수 있을 때 클로저 closure 라고 부릅니다.

클로저를 이용하면 데코레이터나 partial apply 된 함수를 만들기 편리합니다.

데코레이터와 클로저

저번에 만든 maybe 데코레이터를 다시 보겠습니다.

def maybe(f):
  def wrapper(x):
    if x is not None:
      return f(x)
  return wrapper

위 코드를 보면 함수 wrapper에서 바깥에 있는 함수인 maybe의 인자 f를 가져다 쓰는 것을 볼 수 있습니다.

함수 wrapper가 함수 안에 있는 함수이고 클로저이기 때문에 가능합니다.

몰라도 되는 것

우리는 자동차 엔진의 구조나 원리를 정확히 몰라도 운전하는 법만 알면 운전을 잘 할 수 있습니다.

사람들마다 관심의 대상과 정도가 다르고 도구를 활용하는 목적이 다릅니다.

따라서 어느 수준까지 알아야 하는지는 개인이 판단하면 되겠습니다.

자동자 엔진의 구조가 궁금한 사람은 깊게 공부를 하면 됩니다.

그저 운전이 좋은 사람은 엔진 공부를 할 필요가 없습니다.

운전이 싫은 사람은 택시를 타도 됩니다.

차가 싫은 사람은 지하철을 타도 됩니다.

클로저 원리

저 같이 자동자 엔진이 궁금하실 분들을 위해 더 적어봅니다.

파이썬에서 클로저를 구현한 원리는 아래와 같다고 합니다.

함수 객체 내부에 __closure__ 속성을 만들고 여기에 필요한 값을 저장

위에서와 같이 간단한 클로저를 만들어봅니다.

def outside():
  n = 1
  def inside():
    print(n)
  return inside

여기에서는 확인을 위해 함수 outside가 함수 inside를 리턴하도록 했습니다.

클로저 함수는 아래와 같이 __closure__라는 타입이 튜플인 값을 가지게 됩니다.

>>> f = outside()
>>> type(f.__closure__)
<class 'tuple'>

그리고 이 튜플 안에는 타입이 cell인 값들이 저장되어 있고 이 타입은 cell_contents라는 값을 가지고 있습니다. outside가 가지고 있던 변수 n의 값인 1이 바로 여기에 저장되어 있습니다.

>>> type(f.__closure__[0])
class 'cell'
>>> f.__closure__[0].cell_contents
1

참고한 글

대문 링크

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment