Byeonguk Kim

안녕하세요. 29살의 조금은 늦은 나이로 새롭게 개발자로 시작하는 신입 개발자입니다. 포트폴리오 [https://deaguowl.github.io]

파이썬 08. 클로저

12 Mar 2019 » Python

###2019.03.12 TIL

클로저

클로저(closure)은 닫혀있다는 의미다.
우리가 일반적으로 배운 함수는 output이 input에 의존하여 나와야 하나, 이제는 함수에 초기 값을 넣어주면 그게 상태정보가 되고 그 상태정보에 따라 내부에서 함수를 호출했을 때 새로운 input과 내부의 상태정보를 함께 연산하여 새로운 출력값을 나타낼 수 있게 된다.
즉 함수 내부에 상태 정보를 클로징하고 있다하여 클로저라고 부른다.
원래 함수는 실행 이후에 스택프레임이 사라지면서 사라져야 하지만 클로저는 주도권만 주고 그대로 살아 있다.

전제조건

파이썬은 first class function을 지원한다.

first class function

  1. 매개변수로 함수를 줄 수 있다.
  2. return 값으로 함수를 줄 수 있고 함수 내부에 함수 정의 가능
  3. 함수를 변수에 할당할 수 있다.

따라서 함수 내부에 새로운 함수를 정의할 수 있다. 이것을 기본 전제조건을 가지고 클로저를 만들기 위한 조건이 있다.

클로저 생성 조건

그럼 이제 파이썬에서 클로저를 만들기 위한 조건을 정리해보자.

  • 중첩 함수(Nested Function)를 갖는다.
  • 중첩 함수는 자신을 감싸고 있는 함수 영역(부모함수)의 변수를 참조하고 있다.
    • 만약 부모 함수의 변수를 변경하고 싶으면 nonlocal로 참조한다고 설정해주어야 한다.
  • 부모함수는 중첩 함수(자식 함수)를 반환한다.
  • 새로운 변수에 부모함수를 할당해주어야 한다.
    • 새로운 변수에 새로운 값을 넣게 되면 내부 상태정보와 함께 새로운 출력값을 나타낸다.

클로저 예시)

def account(clnt_name, balance):  
    def change_money(money):   #매개변수도 지역변수 이다.
        nonlocal balance            #부모 함수의 변수를 변경하기 위해 nonlocal을 사용한다.
        balance += money      #balance 는 account의 지역변수이다. global도 아니다 
        return (clnt_name, balance)
    return change_money
my_acnt=account("greg", 5000)    #원래라면 함수 호출 이후에 스택프레임이 사라져야 하지만
my_acnt(1000)   # ('greg', 6000)   #내부의 상태정보를 가지고 있다가 새로운 출력값을 나타낸다.

클로저는 class를 사용할 수 없을 때 쓴다????

파이썬에서는 class를 지원하기 때문에 클로저의 효용가치가 많이 떨어진다.
왜냐하면 굳이 클로저로 구현하지 않고 클래스를 만들어서 클래스 내부에 함수를 정의해 놓으면 언제든지 객체를 만들어서 해당 인스턴스를 불러올 수 있기 떄문이다.
따라서 클로저 같은 경우 class를 지원하지 않는 자바스크립트와 같은 언어에서 class를 재현하기 위해 사용한다. 즉 프로토타입 기반의 언어인 자바스크립트는 클로저를 통해서 클래스 기반 언어처럼 캡슐화, 모듈화 작업을 수행할 수 있다.

참조 : 자바스크립트 클로저(Closure)