2014년 9월 21일 일요일

Python - 클로저(Closure) 쉽게 생각하기

오전 8:28 Posted by jonnung 1 comment


함수 안에 다른 함수가 정의된 함수를 중첩 함수(Nested Function) 이라고 한다.
중첩 함수는 자신을 감싸고 있는 함수가 가진 변수에 접근 할 수 있다. 이건 자바스크립트(Javascript)도 동일한 특성이다. 

일단 간단한 예제 코드를 살펴보자.
#-*- coding: utf-8 -*-
 
def print_hello(msg):
    def inner_print():
         # nonlocal msg  # python3.x에만 있는 키워드
        print('Hello %s' % msg)
    return inner_print
 
printer = print_hello('jonnung')

printer()  # Hello jonnung

print_hello() 함수는 'jonnung'을 전달 받아 호출 되었고, 반환된 inner_print함수는 printer 변수에 할당 되었다.
printer() 함수의 실행 결과로 출력되는 값으로 알 수 있는 사실은 print_hello()의 실행이 종료 되었더라도 전달된 값(msg)이 기억되고 있는 것을 알 수 있다.

이러한 코드를 파이썬에서는 클로저(Closure)라고 한다.
그리고 감싸는 함수 안에 변수는 현재 네임스페이스상에서 함수가 삭제되더라도 사라지지 않는다.
del print_hello
 
printer()  # Hello jonnung

결국 중첩 함수가 감싸진 영역안에 변수를 참조할때 클로저를 갖는다고 할 수 있다.

그럼 이제 파이썬에서 클로저를 만들기 위한 조건을 정리해보자.
  • 중첩 함수(Nested Function)를 갖는다.
  • 중첩 함수는 자신을 감싸고 있는 함수 영역(부모함수)의 변수를 참조하고 있다.
  • 부모함수는 중첩 함수(자식 함수)를 반환한다.
여기서 한가지 물음이 생길 수 있겠다. 그렇다면 클로저는 언제 사용해야 할까?
클로저는 전역 변수를 사용하지 않기 위함과 내부 데이터에 대한 은닉을 위해서 활용할 수 있겠다.
그리고 객체지향에 대한 문제점의 해결책이 될 수 있다. 적은 메소드(대부분 1개?)를 갖는 클래스에 대한 대체로 클로저를 활용한 코드는 좀 더 우아한 방법이 될 수도 있다고 한다. 

위 샘플 코드의 실행 결과와 추가적인 예제는 아래 IPython Notebook에서 자세히 확인 할 수 있다.



댓글 1개:

  1. 잘 봤습니다 감사합니다. nbviewer에 문제가 있는지 503 에러가 뜨네요

    답글삭제