클로저에 대한 개념은 Class로 구현한 Closure에 써놈
클로저 정리 : 한 클래스 or 함수 내에서 shared 데이터 쓰는거 마냥 data를 공유(공통)으로 쓰는 방식
말로풀자면 작업 1,2,3,4,5 가 있는데
1작업이 30% 정도 진행되고 있고 2작업이 급하게 해야하는 상황일때,
1작업을 중단하고 2작업을 끝낸 후, 1의 작업을 마저 한다. 라는 기능이 가능해지는 격
1작업스코프를 벗어났음에도 1작업이 어디까지 했는지 알 수 있기 때문에 이런 기능이 구현됨
보기전에 봐야될 개념
내부 함수 depth에 따라서 지역,비지역 함수가 나뉜다.
# outer(), inner() 함수 입장에서 전역(global) 범위
def outer():
# outer() 함수 입장에서 지역(local) 범위
# inner() 함수 입장에서 비지역(nonlocal) 범위
def inner():
# inner 함수 입장에서 지역(local) 범위
주로 봐야될 부분은
1. 클로저 형식
2, 잘못된클로저 사용 (mutable VS immutable 임뮤타블일땐 nonlocal을 사용해줘야한다.)
3. 클로저기능이 되는 이유
1. 클로저 형식 ( call by reference , mutable 인 경우 )
----(1). 외부함수의 자유변수를 내부함수에서 사용한다
----(2). 외부함수에서 내부함수를 return 해준다 ★★ 여기서 "averager()" 가 아니라 "averager" 이렇게 리턴
----(3). 내부함수에서 외부함수의 자유변수를 return해줘야함
2. 클로저의 잘못된 예 ( call by value , immutable 인 경우 )
int형은 immutable 즉 call by value임. 따라서 nonlocal을 써줘야함
외부함수의 변수는 내부함수에서 읽기는 가능하지만 쓰기가 불가능 하다.
[ ] 리스트는 mutable이므로 읽고 쓰기가 가능. 왜냐면 쓰기를 해도 ID주소가 바뀌지 않기때문
3. 클로저 제대로 쓴 예 ( call by value , immutable 인 경우 )
immutable(call by value) 인 int형 값을 클로저로 사용 하고 싶으면
"nonlocal" 로 Free Variable(nonlocal지역)을 명시해줘서 써야 한다.
4.
avg_closure1 = closure_ex1()
이 두 함수를 프린팅 해보면 알 수 있다
closure 기능을 씀으로써 자유변수에 대한 data가 따로 복사되어 사용가능한거임
콘솔창
전체 코드
# Chapter05-03
# 파이썬 심화
# 클로저 심화
# 클로저(Closure) 사용
def closure_ex1():
# Free variable 자유변수
series = []
# 클로저 영역
def averager(v):
# series = [] # 주석 해제 후 확인
series.append(v)
print('inner >>> {} / {}'.format(series, len(series)))
return sum(series) / len(series)
return averager
avg_closure1 = closure_ex1()
print(avg_closure1(15))
print(avg_closure1(35))
print(avg_closure1(40))
print()
print()
# function inspection
print(dir(avg_closure1))
print()
print(dir(avg_closure1.__code__))
print()
print(avg_closure1.__code__.co_freevars)
print()
print(dir(avg_closure1.__closure__[0]))
print()
print(avg_closure1.__closure__[0].cell_contents)
print()
print()
# 잘못된 클로저 사용
def closure_ex2():
# Free variable
cnt = 0
total = 0
def averager(v):
cnt += 1 # cnt = cnt + 1
total += v
return total / cnt
return averager
avg_closure2 = closure_ex2()
# print(avg_closure2(15)) # 예외
# Nonlocal -> Free variable
def closure_ex3():
# Free variable
cnt = 0
total = 0
def averager(v):
nonlocal cnt, total
cnt += 1
total += v
return total / cnt
return averager
avg_closure3 = closure_ex3()
print(avg_closure3(15))
print(avg_closure3(35))
print(avg_closure3(40))
print()
print()
'C++,python (인프런+사이트) > python 파이썬 정리' 카테고리의 다른 글
Generator 제너레이터 ( Yield ) (0) | 2022.04.04 |
---|---|
데코레이터 (0) | 2022.04.03 |
Class로 구현하는 클로저 기능 (0) | 2022.04.03 |
람다 맵 리듀스 필터 (0) | 2022.04.02 |
딕셔너리 고급문법(hash table) (0) | 2022.04.02 |
댓글