소개
Python에서 함수는 일급 객체 함수(First-Class Function) 입니다.
일급 객체 함수는 함수를 변수처럼 사용할 수 있다는 의미입니다. argument 로 넘겨줄수 있으며, return 할수도 있고, assign도 할 수 있습니다.
이러한 특징을 이용해서 Closure 을 만들 수 있는데요. Closure가 무엇인지? 언제쓰면 좋은지? 어떻게 구현하는지?에 대해서 정리를 해보도록 하겠습니다.
Closure 가 무엇인가?
Closure는 일종의 프로그래밍 기법입니다. 위키페디아에서 말하기를 일급 객체 함수의 개념을 이용하여 scope에 묶인 변수를 바인딩 하기 위한 일종의 기술이라고 명시되어 있습니다.
간단한 예제 코드를 통해서 이 정의에 대한 내용을 한번 살펴보겠습니다.
def outer_func(x):
def inner_func():
print(x)
return inner_func
myfunc = outer_func("hello")
myfunc()
""" 출력
hello
"""
- 외부함수(outer_func)와 내부함수(inner_func)를 정의하고,
- 내부함수는 외부함수가 인수로 받은 변수 x를 출력하는 함수입니다.
- outer_func(“hello”)를 호출하면 inner_func의 참조를 복사한 내부함수를 반환하고,
- 반환한 내부함수를 실행하면 외부함수가 받은 인수인 hello를 출력합니다.
위의 예제를 기반으로 위키페디아에서 정의하고 있는 내용을 풀어보면 아래와 같습니다.t
- scope(접근할 수 있는 유효 범위)에 묶인 변수(x)를 바인딩 하기 위해 nested function(내부함수)과 nonlocal 변수(x)를 사용하는 기술
일반적으로 함수가 호출되고 return으로 반환되면 그 함수 scop에서 사용어진 변수들은 모두 소멸됩니다. 그런 개념에서 위의 예제 코드를 접근해 보면 outer_func(“hello”) 를 통해서 inner_func 참조값을 return 하였으니, outer_func에서 받은 인수인 x도 함께 소멸이 되어야 하며, return 된 inner_func 참조값을 실행하더라도 소멸된 x값에 접근을 할 수 없어야 한다고 생각 할 수 있습니다.
그러나 closure 는 외부함수가 호출되고 return되어 소멸되더라도, 내부함수를 통해 nonlocal 변수를 바인딩하여 사용할 수 있습니다.
Closure 를 쓰면 무엇이 좋은가?
Closure 를 사용하면 아래와 같은 이득이 있습니다.
- Global Values 를 사용할 필요가 없습니다.
- 이 말은 외부함수에 쌓여 있는 내부함수에서 공통적으로 사용할 변수가 있다면, 굳이 Global 변수를 사용하지 않고 nonlocal 변수(내부함수 기준)를 사용하면 됩니다.
- Global 변수의 사용은 프로그램의 사이즈가 커질 경우 디버깅하기가 힘들어 지기 때문에 가급적 사용하지 않는 것이 좋습니다.
def outer_func(x):
num = 1 # global 변수 대신 사용 가능
def inner_func():
nonlocal num # nonlocal
num = num + x
print(num)
return inner_func
myfunc = outer_func(10)
myfunc()
""" 출력
11
"""
- 몇몇의 함수를 가지고 있을 때, class 대신에 가볍게 구현해서 사용할 수 있습니다.
- decorators를 구현할 수 있습니다.
어떻게 구현을 하는가?
Closure 구현을 위한 조건은 위에서 본 예제에서도 알 수 있듯이 아래와 같은 3가지의 조건이 필요합니다.
- nested function 을 가지고 있어야 합니다.
- nested function 이 nonlocal 변수를 참조합니다.
- 둘러싸고 있는 scop(외부함수)이 nested function 을 return 해야 합니다.