Python

Python 문법 기초 18 - 클로저(closure)

코딩탕탕 2022. 10. 22. 16:28

 

클로저(closure) : scope에 제약을 받지않는 변수를 포함하고 있는 코드 블록이다.

내부함수의 주소를 반환함으로 해서 함수 내의 지역변수를 함수 밖에서 참조 가능

 

def funcTimes(a, b):
    c = a * b
    return c

print(funcTimes(2, 3))

kbs = funcTimes(2, 3)
print(kbs)
kbs = funcTimes
print(kbs)
print(kbs(2, 3))
print(id(kbs), id(funcTimes))

del funcTimes # 함수 삭제
# funcTimes() # 함수가 삭제되었음으로 에러 발생
print(kbs(2,3)) # 주소, 값은 같지만 새로운 함수이므로 삭제되지 않음

mbc = sbs = kbs
print(mbc(2,3))


<console>
6
6
<function funcTimes at 0x0000016EFE49ACA0>
6
1576224271520 1576224271520
6
6

 

클로저를 사용하지 않은 경우

print('클로저를 사용하지 않는 경우')
count = 0
def out():
    count = 0
    def inn():
        nonlocal count # count의 값을 out으로 하기 위해서 사용!
        count += 1
        return count
    # inn() # 같은 방식
    imsi = inn() # 같은 방식
    return imsi # 같은 방식
    
# print(out()) err
print(out())
print(out())


<console>
1
1

 

지역변수와 전역변수를 잘 이해해야 된다.

 

클로저를 사용한 경우

print('\n클로저를 사용한 경우')
count = 0
def outer():
    count = 0
    def inner():
        nonlocal count # count의 값을 out으로 하기 위해서 사용!
        count += 1
        return count
    return inner # <=== 이것이 클로저 : 내부함수의 주소를 반환

var1 = outer() # inner 의 주소를 리턴받음
print(var1)
print(var1())
print(var1())
print(var1())
print(var1())


<console>
<function outer.<locals>.inner at 0x000002C1D25761F0>
1
2
3
4

내부함수의 주소를 반환함으로 해서 함수 내의 지역변수를 함수 밖에서 참조 가능하다.

 

print('*** 수량 * 단가 * 세금을 계산하는 함수 만들기')
# 분기별로 세금은 동적이다.
def outer2(tax): # local 변수.
    def inner2(su, dan):
        amount = su * dan * tax
        return amount
    return inner2

# 1분기에는 tax가 0.1 부과
q1 = outer2(0.1) # inner2의 주소가 반환 됨.
result1 = q1(5, 50000)
print('result1 : ', result1)
result2 = q1(1, 10000)
print('result2 : ', result2)

# 2분기에는 tax가 0.05 부과
q1 = outer2(0.05) # inner2의 주소가 반환 됨.
result3 = q1(5, 50000)
print('result3 : ', result3)
result4 = q1(1, 10000)
print('result4 : ', result4)


<console>
*** 수량 * 단가 * 세금을 계산하는 함수 만들기
result1 :  25000.0
result2 :  1000.0
result3 :  12500.0
result4 :  500.0

세금을 구하기 위해 수량, 단가, 세금을 구하는 함수의 주소를 리턴받아서 실행시켜준다.