파이썬은 데코레이터(decorator)라는 기능을 제공한다. 지금까지 클래스에서 메서드를 만들 때 @staticmethod , @classmethod, @abstractmethod 등을 붙였는데, 이렇게 @ 로 시작하는 것들이 데코레이터이다.
데코레이터는 함수를 수정하지 않은 상태에서 추가 기능을 구현할 때 사용한다.
예를 들어 함수의 시작과 끝을 출력하고 싶다면 다음과 같이 함수 시작, 끝 부분에 print를 넣어주어야한다.
def hello():
print("hello 함수의 시작")
print("hello")
print("hello 함수의 끝")
def world():
print("world 함수의 시작")
print("world")
print('world 함수의 끝')
hello()
world()
만약 다른 함수도 시작과 끝을 출려하고 싶다면 함수를 만들 때마다 print를 넣어야 한다. 따라서 함수가 많아지면 매우 번거로워 진다. 이 경우에 데코레이터를 활용하면 편리해진다.
def trace(func):
def wrapper():
print(func.__name__, "함수 시작")
func()
print(func.__name__, '함수 끝')
return wrapper
def hello():
print("hello")
def world():
print("world")
trace_hello = trace(hello)
trace_hello()
trace_world = trace(world)
trace_world()
이제 @을 사용해서 좀 더 간편하게 데코레이터를 사용해보자. 다음과 같이 호출할 함수 위에 @데코레이터 형식으로 지정한다.
def trace(func):
def wrapper():
print(func.__name__, "함수 시작")
func()
print(func.__name__, '함수 끝')
return wrapper
@trace
def hello():
print("hello")
@trace
def world():
print("world")
hello()
world()
데코레이터를 그림으로 표현하면 다음과 같은 모양이 된다.

함수에는 데코레이터를 여러개 지정할 수 있다. 이때 데코레이터가 실행되는 순서는 위에서 아래 순이다.
매개변수와 반환값을 처리하는 데코레이터는 어떻게 만드는지 알아보자
def trace(func):
def wrapper(a, b): # 호출할 함수 add(a, b)의 매개변수와 똑같이 지정
r = func(a, b)
print('{0}(a={1}, b={2}) -> {3}'.format(func.__name__, a, b, r))
return r
return wrapper
@trace
def add(a, b):
return a + b
print(add(10, 20))
add(a=10, b=20) -> 30
30