프로그래밍 언어에서 클로저란
퍼스트클래스 함수를 지원하는 언어의 네임 바인딩 기술입니다.
먼저 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을 사용할 수 있는 것입니다.