1. Decorator가 중요한 이유
데코레이터를 사용하기는 쉽지만, 작성하기는 어렵다고 한다.
왜냐하면 여러가지 개념들이 합쳐져 있기 때문이다.
파이썬의 전반적인 과정을 이해해야 가능하다.
- Closure(클로저) -> [TIL] Python basic 33: Closure
- firt-class(일급 함수) -> [TIL] Python basic 31: First-class
- 가변 인자(*args, **args) ->[TIL] Python basic 12: Method
- 인자 풀기(unpacking) ->[TIL] Python basic 12: Method
- 파이썬이 소스 코드를 불러오는 자세한 과정
그렇다면 왜 데코레이터를 배워야하는가???
- 장점
중복 제거, 코드 간결, 공통 함수 작성
- 프로그래밍 언어의 패러다임이 이런 방식으로 진행된다.
로깅, 프레임워크, 유효성 체크
- 이러한 기능들을 가지는 함수를 만들어서 공통 기능으로 사용 가능하다.
- 파이썬 기반 프레임 워크의 많은 비중이 데코레이터로 설계되어 있다.
조합해서 사용 용이
단점
- 가독성 감소
- 특정 기능에 한정된 함수는 단일 함수로 작성하는 것이 유리
- 디버깅 불편
from 인프런 파이썬 중급
2. Closure의 기본 패턴
- 데코레이터는 클로저와 형태가 유사하다.
- 그래서, 특히 클로저를 이해하지 못하면 데코레이터를 만들 수 없다.
- 자바에서는 어노테이션이라 한다.
|
|
3. Decorator 실습 예제
- decorator를 직접 구현해보자.
- 모든 함수가 실행될 때마다 performance를 체크하는 함수를 만들 것이다.
perf_counter
: time module에 있는 method로, 코드 실행 시간을 측정한다.
3.1 Decorator로 사용할 function 만들기
|
|
3.2 Decorator 없이 사용하기
- 그러면 데코레이터를 사용하지 않고, 위 function을 사용해보자.
|
|
위 코드의 매커니즘에 대해 알아보자.
첫 번째, perf_clock(func) 의 func 인자에
time_func
을 할당했다.두 번째, perf_clock(time_func)의 return 값인
perf_clocked
fuction을 none_deco1에 할당했다.세 번째,
중첩 함수인 perf_clocked(*args) function에 time_func가 할당된 상태로, none_deco1에 할당된다.
그러면 인자
func
그리고*args
중에서 할당되지 않은 인자는*args
다.
다섯 번째,
none_deco1(1.5)를 선언하면서
*args
에 1.5가 할당된다.none_deco2(100, 150, 250, 300, 350)은
*args
에 100, 150, 200, 300, 350이 할당.
이처럼 지난 first-class에서 알아본 partial처럼 하나씩 고정인수를 만들어간다.
이 방식이 가능한 이유는 closure의 개념을 이용했기 때문이다.
3.3 Decorator로 사용하기
- 이번에는 데코레이터를 사용해본다.
- decorator를 사용하니 코드가 훨씬 간결해진 걸 확인해보자.
|
|
Decorator를 사용하면 별도의 변수에 함수를 할당할 필요가 없다.
@perf_clock
을 time_func와 sum_func 위에 각각 입력하여 time_func와 sum_func의 decorator로 사용한다.위에 각각 입력하는 의미는
perf_clock
의func
인자에 time_func와 sum_func을 할당하여 고정시킨다.이 다음으로 time_func(1.5) 와 time_func(100, 150, 250, 300, 350)처럼
*args
가변인자를 사용하여 할당한다.
- 이처럼 decorator는 closure, firt-class, 가변인자, packing & unpacking 개념을 사용한다.