###2019.03.12 TIL
클로저
클로저(closure)은 닫혀있다는 의미다.
우리가 일반적으로 배운 함수는 output이 input에 의존하여 나와야 하나, 이제는 함수에 초기 값을 넣어주면 그게 상태정보가 되고 그 상태정보에 따라 내부에서 함수를 호출했을 때 새로운 input과 내부의 상태정보를 함께 연산하여 새로운 출력값을 나타낼 수 있게 된다.
즉 함수 내부에 상태 정보를 클로징하고 있다하여 클로저라고 부른다.
원래 함수는 실행 이후에 스택프레임이 사라지면서 사라져야 하지만 클로저는 주도권만 주고 그대로 살아 있다.
전제조건
파이썬은 first class function을 지원한다.
first class function
- 매개변수로 함수를 줄 수 있다.
- return 값으로 함수를 줄 수 있고 함수 내부에 함수 정의 가능
- 함수를 변수에 할당할 수 있다.
따라서 함수 내부에 새로운 함수를 정의할 수 있다. 이것을 기본 전제조건을 가지고 클로저를 만들기 위한 조건이 있다.
클로저 생성 조건
그럼 이제 파이썬에서 클로저를 만들기 위한 조건을 정리해보자.
- 중첩 함수(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를 재현하기 위해 사용한다. 즉 프로토타입 기반의 언어인 자바스크립트는 클로저를 통해서 클래스 기반 언어처럼 캡슐화, 모듈화 작업을 수행할 수 있다.