Decorator
장식하다, 꾸미다는 의미를 가진 decorate에 er/or을 붙인 말로 장식자, 도배업자 등을 의미한다. 즉, 방을 벽지나 커튼으로 꾸미듯이 기존의 코드, 함수에 여러 기능을 추가하는 구문으로 함수 위에 @로 시작한다.
이전에 2022.09.17 - [Flask] REST API 만들기 내 소스에서 @app.route가 바로 데코레이터에 해당한다.
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
이 글에서는 데코레이터를 생성하고, 사용하는 방법을 정리한다. 만약 1급 객체, 클로저에 대한 개념이 없다면 우선적으로 숙지하는 것을 권한다.
참고 : 2022.10.04 - [Python] Closure
데코레이터 생성
데코레이터는 함수를 수정하지 않으면서 추가 기능을 구현할 때 사용한다.
예로 들어 함수의 시작과 끝을 출력하는 기능을 추가한다면, 함수 각각에 print 문 등을 추가해야 할 것이다.
def hello():
print('hello 함수 시작')
print('hello')
print('hello 함수 끝')
def world():
print('world 함수 시작')
print('world')
print('world 함수 끝')
hello()
world()
하지만 데코레이터를 사용하면 함수 자체를 수정하지 않고도 시작과 끝을 알리는 기능을 추가할 수 있다.
def hello():
print('hello')
def world():
print('world')
def trace(func): # input : 함수
def wrapper(): # clousure
print(f"{func.__name__} 시작")
func()
print(f"{func.__name__} 종료")
return wrapper
h = trace(hello) # decorator에 함수 전달
w = trace(world)
h() # 실행
w()
@로 데코레이터 사용
데코레이터는 함수 정의 시 @decorator 형식으로 지정하여 간편하게 사용할 수 있다.
def trace(func): # input : 함수
def wrapper():
print(f"{func.__name__} 시작")
func()
print(f"{func.__name__} 종료")
return wrapper
@trace
def hello():
print('hello')
hello()
데코레이터의 실행 흐름은 아래 그림처럼 표현할 수 있다.
💡
함수 정의 시 실행할 decorator는 여러 개를 지정할 수 있다. 개행을 기준으로 나열하며, 나열된 순으로 실행된다.
참고 문서
https://dojang.io/mod/page/view.php?id=2427