프로그래밍/PYTHON

python - Closure

aiemag 2020. 11. 3. 20:57
반응형

python의 closure에 대해 정리합니다.

 


 

다음은 closure의 기본 형태입니다. 12 line의 closure 함수를 호출할 때 10을 인자로 전달하여 inner 함수를 return 하도록 합니다.

 

이제 inner 함수는 nonlocal 변수인 x의 값을 메모리에 저장하고 있다가 실제로 inner 함수가 호출될 때 저장된 x의 값과 inner 함수로 전달된 y 값의 합을 return 합니다.

 

이렇게 기술적으로 inner 함수를 반환하여 사용하는 형태를 closure 라고 합니다. 이 때 inner 함수는 nonlocal 변수의 값을 메모리상에 계속 가지고 있을 수 있으며 활용하게 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python3
 
def closure(x):
    
    def inner(y):
        return x+y
 
    return inner
 
 
def main():
    ret = closure(10)
    print(ret(5))
 
 
if __name__ == "__main__":
    main()
cs

 

※ closure의 사전적 정의는 'first-class function을 지원하는 언어에서 유효 범위의 이름을 바인딩하는 기술' 이라고 합니다. 

※ first-class citizen 또는 first-class object는 일급 객체라고 하고 프로그래밍 언어에서 first-class citizen 속성을 가진다는 것은 어떤 개체를 다른 개체의 매개변수로 전달하거나, 함수의 반환값으로 사용하거나, 변수에 값으로 할당할 수 있다는 것을 의미합니다.

※ first-class function은 함수가 first-class citizen 속성을 가지는 것을 말합니다.
- 해당 설명은 '파이썬답게 코딩하기 - 저자 : 심경섭 님'의 책을 참조하였습니다.

 


 

다음 code는 logging 함수를 사용하는데 21 line을 보면 closure에서 사용될 함수와 파라미터들을 지정합니다.

 

이제 매번 모든 파라미터를 입력할 필요 없이 고정된 파라미터들은 closure 형태인 partial 함수 내의 wrapper 함수를 이용하여 고정되게 됩니다.

 

이후 inner 함수인 wrapper 함수를 이용하여 logging 함수에 고정 매핑된 파라미터들은 별도 입력 필요없이 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/python3
 
def partial(func, *partial_args):
 
    def wrapper(*extra_args):
        args = list(partial_args)
        args.extend(extra_args)
 
        return func(*args)
 
    return wrapper
 
 
def logging(year, month, day, title, content):
    print("%s-%s-%s %s:%s" % (year, month, day, title, content))
 
 
def main():
    logging("2020""11""11""weather""sunny")
 
    p = partial(logging, "2020""11""11")
    p("news""gold in the bank has been stolen.")
    p("news""COVID-19 has spread in nursing hospital.")
 
 
if __name__ == "__main__":
    main()
 
cs

 

closure 의 partial argument 처리를 간단하게 지원하는 functools library의 partial 함수의 사용예입니다.

 

위의 예에서 partial 함수를 직접 구현하지 않아도 바로 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3
 
from functools import partial
 
def logging(year, month, day, title, content):
    print("%s-%s-%s %s:%s" % (year, month, day, title, content))
 
 
def main():
    logging("2020""11""11""weather""sunny")
 
    p = partial(logging, "2020""11""11")
    p("news""gold in the bank has been stolen.")
    p("news""COVID-19 has spread in nursing hospital.")
 
 
if __name__ == "__main__":
    main()
 
cs

 

출력예는 먼저 생각해보고 실행하여 결과와 비교해보시면 됩니다.

반응형

'프로그래밍 > PYTHON' 카테고리의 다른 글

python - Iterable, Iterator  (0) 2021.02.03
python - Decorator  (4) 2021.01.22
python - map(), filter(), reduce() usage  (0) 2020.10.27
python - global, nonlocal keyword  (0) 2020.10.25
python 어렵지 않아요  (6) 2020.06.08