본문 바로가기
코딩 연습/코딩배우기

[python] 파이썬 중첩함수(Nested Function)와 클로저(Closure)

by good4me 2020. 9. 15.

goodthings4me.tistory.com

 

■ 클로저(Closure)는 함수를 만들어서 반환하는 함수 - 파이썬의 함수도 개체이기 때문에 가능

def maker1(m):
    
    def inner():  # 함수 안에 정의된 함수(nested 함수)
        print('closure ' * m)
    
    return inner()  # nested 함수 실행 후 반환

f1 = maker1(2)  # closure closure 
print(f1)  # None



def maker2(m):
    
    def inner():
        print('closure ' * m)
    
    return inner  # nested 함수 반환

f2 = maker2(3)  # print 함수 실행 X
f2()  # closure closure closure --> print('clouser ' * m) 실행, m의 값 참조

print(f2)  # inner 함수 리턴 확인(함수 오브젝트 리턴)
# <function maker2.<locals>.inner at 0x000001F08EC25C80>

# 이때, 매개변수 m은 maker 함수 안에서 선언된 변수이고, 실행이 종료된 함수(maker)의 변수는 소멸되는 것이 정상인데,  어디에 있을까?

# 이렇게 함수의 안쪽에 위치한 함수(nested func)가 자신이 필요한 변수의 값을 어딘가에 저장해 놓고 호출 시 참조하는 테크닉을 "클로저(Clouser)"라 한다.

※ 변수값 m의 위치는?

print(type(f2))  # <class 'function'>

print(dir(f2))  # '__closure__'

print(f2.__closure__)  # (<cell at 0x000001F08E83D7F8: int object at 0x00007FF8DF8B9380>,)

print(type(f2.__closure__))  # <class 'tuple'>

print(f2.__closure__[0])
# <cell at 0x000001F08EBE1678: int object at 0x00007FF8DF8B9380>

print(dir(f2.__closure__[0]))  # 'cell_contents'

print(f2.__closure__[0].cell_contents)  # 3

# 변수 m의 값의 위치는 __clouser__의 인덱스 0의 위치에 저장된 객체의 변수(속성)인 cell_contents에 있다.

good4me.co.kr

 

※ 변수 2개인 경우는?

def maker3(m, n):
    
    def inner():
        print(n * m)
    
    return inner

f3 = maker3(4, 'Closure')

f3()  # ClosureClosureClosureClosure

print(f3.__closure__)
# (<cell at 0x000001F08EBE1E28: int object at 0x00007FF8DF8B93A0>, 
# <cell at 0x000001F08ECAD048: str object at 0x000001F08E838B90>)

print(f3.__closure__[0].cell_contents)  # 4

print(f3.__closure__[1].cell_contents)  # Closure

# 변수는 __closure__의 인덱스에 저장됨

 

※ 클로저(Closure) 응용

def outer(tag):
    tag = tag
    
    def inner_html(text):
        contents = text
        print('<{0}>{1}<{0}><br/>'.format(tag, contents))
    
    return inner_html

p_tag = outer('h2')

p_tag('파이썬 중첩함수(Nested Func)와 클로저(Closure)')


[실행 결과]
<h2>파이썬 중첩함수(Nested Func)와 클로저(Closure)<h2><br/>

 

[참고 자료] 윤성우의 열혈파이썬 중급편

 

댓글