728x90
4.9 데코레이터
파이썬에서 제공하는 데코레이터
는 함수를 장식한다는 뜻에서 붙여진 이름이다. 그렇다면 언제, 어떻게 사용해야 할까??
데코레이터는 함수를 수정하지 않은 상태에서 추가 기능을 구현할 때 사용한다.
개념 및 예시
ex) hello 함수, world 함수
- 기존함수 hello, world
def hello() :
print('hello')
def world() :
print('world')
이때, 각각의 함수의 시작과 끝
을 출력하는 코드를 넣고 싶다. 그러면 아래와 같이 함수를 수정해주면 된다.
def hello() :
print('hello 함수 시작')
print('hello')
print('hello 함수 끝')
def world() :
print('world 함수 시작')
print('world')
print('world 함수 끝')
하지만, 위와 같이 일일이 함수를 넣어준다면 전체적인 코드도 길어지고 각각의 함수에 일일이 넣어줘야 한다는 불편함이 있다.
이럴 때 데코레이터
를 활용하면 편리하게 사용할 수 있다.
def trace(func) :
def wrapper() : # 함수를 감싼다고 해서 wrapper. 이름을 다른 거 써도 상관없음
print(func.__name__, '함수 시작')
func()
print(func.__name__, '함수 끝')
return wrapper
def hello() :
print('hello')
def world() :
print('world')
trace_hello = trace(hello) # 데코레이터에 호출할 함수(hello)를 넣음
trace_hello()
trace_world = trace(world) # 데코레이터에 호출할 함수(world)를 넣음
trace_world()
정리하면, 원래는 함수의 시작과 끝에 내용을 출력하려면 함수를 직접 수정
해야 했지만
그 과정이 너무 번거로우니까
함수의 시작과 끝을 출력하도록 하는 데코레이터 함수를 만들어서시작과 끝을 출력하고 싶은 함수
를 데코레이터 함수의 매개변수로 넣어주기만 하면 되도록 했다.
ex) 함수 실행 시간을 측정하는 데코레이터
(매개변수로 입력되는 함수에 매개변수
가 필요할 수 있기 때문에 *args
, **kwargs
를 추가함)
def make_timer(func) :
def wrapper(*args, **kwargs) :
t1 = time.time()
ret_val = func(*args, **kwargs)
t2 = time.time()
print('소요 시간 : ' , t2- t1) # 원하는 문장
return ret_val
return wrapper
def hello() :
print('hello')
def world() :
print('world')
hello_time = make_timer(hello) # 데코레이터에 호출할 함수(hello)를 넣음
hello_time()
world_time = make_timer(world) # 데코레이터에 호출할 함수(world)를 넣음
world_time()
마찬가지로 각각의 함수의 실행 시간을 측정하는 코드를 넣는게 번거로우니까
실행 시간을 측정할 수 있는 데코레이터 함수(make_timer)를 만들어서실행 시간을 측정하고 싶은 함수
를 데코레이터 함수의 매개변수로 넣어주기만 하면 되도록 했다.
@를 사용한 데코레이터
- 앞서 소개한 방식
def trace(func) :
def wrapper() : # 함수를 감싼다고 해서 wrapper. 이름을 다른 거 써도 상관없음
print(func.__name__, '함수 시작')
func()
print(func.__name__, '함수 끝')
return wrapper
def hello() :
print('hello')
def world() :
print('world')
trace_hello = trace(hello) # 데코레이터에 호출할 함수(hello)를 넣음
trace_hello()
trace_world = trace(world) # 데코레이터에 호출할 함수(world)를 넣음
trace_world()
@
을 사용한 방식
def trace(func) :
def wrapper() : # 함수를 감싼다고 해서 wrapper. 이름을 다른 거 써도 상관없음
print(func.__name__, '함수 시작')
func()
print(func.__name__, '함수 끝')
return wrapper
@trace # trace라는 데코레이터를 이용한 호출을 원하는 함수에 붙여준다.
def hello() :
print('hello')
@trace # trace라는 데코레이터를 이용한 호출을 원하는 함수에 붙여준다.
def world() :
print('world')
# 두 개의 함수는 @trace를 붙였으니까
# trace 데코레이터를 이용해서 호출된다.
hello() # trace_hello = trace(hello)
# trace_hello() 와 동일한 동작
world() # trace_world = trace(world)
# trace_world() 와 동일한 동작
이와 같이 데코레이터는 함수를 감싸는 형태로 구성되어 있어서 기존 함수를 수정하지 않으면서 추가 기능을 구현할 때 사용한다.
- 출처
https://dojang.io/mod/page/view.php?id=2427
'Python' 카테고리의 다른 글
[파이썬 코드 업] 9-2장. 클래스와 매직 메서드 (0) | 2023.05.07 |
---|---|
[파이썬 코드 업] 9-1장. 클래스와 매직 메서드 (0) | 2023.05.06 |
[파이썬 코드 업] 4-2장. (0) | 2023.05.06 |
[파이썬 코드 업] 4-1장. 프로그래밍 지름길 (0) | 2023.05.05 |
[파이썬 스킬 업] 3장. 리스트 기능 (0) | 2023.04.27 |