🐍 데코레이터
- 이름 그대로 파이썬의 함수를 장식해주는 역할
- 데코레이터는 선언되는 함수 위에 @를 사용해 @decorator 형태로 작성함
- 해당 함수가 실행될 때 데코레이터에서 선언 된 코드가 같이 실행된다
🐍 데코레이터 코드 구조
# 데코레이터는 호출 할 함수를 인자로 받도록 선언합니다.
def decorator(func):
# 호출 할 함수를 감싸는 wrapper 함수를 선언합니다.
def wrapper():
# func.__name__에는 데코레이터를 호출 한 함수의 이름이 들어갑니다.
print(f"{func.__name__} 함수에서 데코레이터 호출")
func()
print(f"{func.__name__} 함수에서 데코레이터 끝")
# wrapper 함수를 리턴합니다.
return wrapper
1. 데코레이터로 사용할 함수를 선언
- func을 인자로 받는다
- 함수 안에 함수가 있는 구조임
- 호출할 함수를 감싸주는 wrapper 함수 선언
@decorator
def decorator_func():
print("decorator_func 함수 호출")
decorator_func()
# result output
"""
decorator_func 함수에서 데코레이터 호출
decorator_func 함수 호출
decorator_func 함수에서 데코레이터 끝
"""
2. 선언되는 함수 위에 @decorator를 추가해 데코레이터를 사용 가능
- @ 뒤에 오는 이름은 내가 선언한 데코레이터 함수 이름을 의미함
- 1번에서 "decorator" 라는 이름으로 함수를 만들었기 때문에 @decorator
정리
데코레이터 함수를 정의한 이후에는 @decorator 형태를 사용해서
특정 함수가 실행될 때, 데코레이터를 같이 실행해줄 수 있다
또는 함수가 실행되기 전, 후에 내가 원하는 코드를 실행 할 수 있음
🐍 데코레이터 예제
내가 실행하는 함수의 실행 시간이 얼마나 걸렸는지 확인하는 코드
# 특정 함수의 실행 시간 구하기
import time
import random
def time_checker(func):
def wrapper():
# 함수가 실행될 때 시간을 저장
start_time = time.time()
# 함수를 실행
func()
# 함수가 종료된 후 시간에 실행될 때 시간을 빼 실행 시간을 구함
executed_time = time.time() - start_time
# 실행 시간을 소수점 5자리까지만 출력
print(f"{func.__name__} 함수의 실행시간 : {executed_time:.05f}s")
return wrapper
@time_checker
def main():
# 함수의 실행 시간을 테스트하기 위해 0.1초 ~ 1초간 sleep
time.sleep(random.randint(1, 10) / 10)
for i in range(10):
main()
# result output
"""
main 함수의 실행시간 : 0.80095s
main 함수의 실행시간 : 0.90009s
main 함수의 실행시간 : 1.00027s
main 함수의 실행시간 : 0.20020s
main 함수의 실행시간 : 0.90011s
main 함수의 실행시간 : 0.60041s
main 함수의 실행시간 : 0.30027s
main 함수의 실행시간 : 0.40024s
main 함수의 실행시간 : 0.10026s
main 함수의 실행시간 : 0.50032s
"""
이런식으로 다양한 활용 가능!
ex) 사용자 권한 체크 - 인증된 사용자만 실행가능하도록 만들기
예를 들어 login_required 라는 데코레이터를 만들어서,
사용자가 인증된 사용자인지 체크하는 코드를 넣은 후,
if 문으로 분기하여 인증 여부에 따라 함수 실행 여부를 나누면 된다.
실제로 많이 사용되는 방식임.
🐍 인자가 있는 함수의 데코레이터 예제
wrapper 함수에 인자를 받아준다.
# 입력받은 인자에 2를 곱해주기
def double_number(func):
def wrapper(a, b):
# 함수에서 받은 인자에 2를 곱해준다
double_a = a * 2
double_b = b * 2
return func(double_a, double_b)
return wrapper
@double_number
def double_number_add(a, b):
return a + b
def add(a, b):
return a + b
print(double_number_add(5, 10)) # 30
print(add(5, 10)) # 15
double_number 데코레이터를 사용할 경우, 각 숫자에 2를 곱해준 값을 기준으로 계산한 결과가 출력되는 것을 확인할 수 있다.
이런식으로 함수에 인자가 있을 때도
데코레이터에서 그 인자를 동일하게 받아서 사용할 수 있다
그리고
어떤 함수에든 데코레이터를 갖다 붙히기만 하면
내가 원하는 방식으로 코드를 실행할 수 있우