-
함수 데코레이터와 클로저Programming/Python 2023. 6. 12. 10:24
함수 데코레이터는 소스 코드에 있는 함수를 표시해서 함수의 작동을 개선할 수 있게 해준다.
데코레이터 ⇒ 다른 함수를 인수로 받는 콜러블 이다.
@decorate def target(): print('running target()') # 위 코드와 아래 코드는 동일하게 동작 def target(): print('running target()') target = decorate(target)
데코레이터는 다른 함수를 인수로 전달해서 호출하는 일반적인 콜러블과 동일하다.
그렇지만 런타임에 프로그램 행위를 변경하는 메타프로그래밍을 할 때 데코레이터가 상당히 편리하다.
요약
- 데코레이트된 함수를 다른 함수로 대체하는 능력이 있다.
- 데코레이터는 모듈이 로딩될 때 바로 실행된다.(데코레이트는 임포트 타임에서 실행, 데코레이트 된 함수는 명시적으로 호출될 때 만 실행)
promos = [] def promotion(promo_func): promos.append(promo_func) return promo_func @promotion def fidelity(order): return ... @promotion def bulk_item(order): return ... @promotion def large_order(order): return ... def best_promo(order): return max(promo(order) for promo in promos) # 이렇게 할 경우 데코레이트 된 함수는 promos 에 등록이 되어있음 따로 추가하는 번거로움이 사라짐
b= 9 # 정상 동작 def f1(a): print(a) print(b) f1(3) b=9 # 에러 발생 : 이유 => 함수 실행시 print(b) 는 함수 내에 선언된 지역 변수를 참조 # 하지만 b=6 은 print(b) 보다 뒤에 선언되기 때문에 에러발생 globals()로 전역변수를 참조명시 def f2(a): print(a) print(b) b= 6 f2(3)
클로저 ⇒ 함수 본체에서 정의하지 않고 참조하는 비전역 변수를 포함한 확장 범위를 가진 함수다.
함수가 비전역 외부 변수를 다루는 경우는 그 함수가 다른 함수 안에 정의된 경우 뿐 이라는 점에 주의
숫자, 문자열, 튜플 등 불변형은 읽을 수만 있고 값은 갱신할 수 없다.
⇒ nonlocal 을 통해서 지역 변수임이 아닌 자유변수임을 명시한다.
functools.lru_cache() Least Recently Used 방식으로 최근 가장 오래 안쓰인 부분을 제거하는 방식으로 캐시 관리
functools.singledispatch() 로 데코레이트 하면 범용 함수가 된다. 자료형에 따라 서로 다른 방식의 연산을 수행하게 된다.
'Programming > Python' 카테고리의 다른 글
[Django] Django Admin 리스트 페이지 사용하기 (0) 2023.06.12 [Fluent Python]객체 참조, 가변성, 재활용 (0) 2023.06.12 [Fluent Python]일급 함수 (0) 2023.06.12 [Fluent Python] 텍스트와 바이트 (0) 2023.06.12 [Fluent Python] 딕셔너리와 집합 (0) 2023.06.12