프로그래밍 언어에서 클로저란
퍼스트클래스 함수를 지원하는 언어의 네임 바인딩 기술입니다.

먼저 free variable 개념부터 알아보겠습니다.
free variable은 코드블럭안에서 사용은 되었지만, 그 코드블럭안에서 정의되지 않은 변수를 뜻합니다.

예제를 살펴보겠습니다.

def outer_func():
    message = 'Hi'

    def inner_func():
        print message

    return inner_func()

outer_func()
>>> Hi

message라는 변수는 inner_func() 안에서 선언되지는 않았지만
사용은 하고 있는데 이런 변수를 free variable이라고 합니다.

이게 어떻게 가능한걸까요?

def outer_func():  #1
    message = 'Hi'  #3

    def inner_func():  #4
        print message  #6

    return inner_func  #5

my_func = outer_func()  #2

print my_func  #7
>>> <function inner_func at 0x1019dfed8>

print dir(my_func)  #8
>>> ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
"""
Python에서 함수는 함수 클래스를 상속받은 객체이기 때문에 내장 변수, 내장 메소드를 갖고 있습니다.
"""

print type(my_func.__closure__) #9
>>> <type 'tuple'>

print my_func.__closure__  #10
>>> (<cell at 0x1019e14b0: str object at 0x1019ea788>,)

print my_func.__closure__[0]  #11
>>> <cell at 0x1019e14b0: str object at 0x1019ea788>

print dir(my_func.__closure__[0])  #12
>>> ['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']

print my_func.__closure__[0].cell_contents  #13
>>> Hi

이렇게 closure 함수는 내장 변수에 Hi라는 값을 저장해놨기 때문에 closure 함수에서 free variable을 사용할 수 있는 것입니다.