데코레이터(Decorator)는 기존 함수의 코드를 직접 수정하지 않으면서 새로운 기능을 추가하는 기능입니다.
표기법(@)
데코레이터도 일종의 함수입니다. 단, 목표하는 함수를 인자로 받아 그 함수 앞뒤로 추가 기능을 구현한 새로운 함수(일반적으로 wrapper라고 부릅니다)를 반환한다는 특징이 있습니다.
def my_decorator(func):
def wrapper():
print("--- 함수 실행 전 ---")
func() # 데코레이터가 적용될 함수
print("--- 함수 실행 후 ---")
return wrapper # 새로운 함수를 반환합니다
def say_hello():
print("안녕하세요!")
dec_say_hello = my_decorator(say_hello) # say_hello 함수를 인자로 받았습니다.
dec_say_hello()
# 출력하면 :
# --- 함수 실행 전 ---
# 안녕하세요!
# --- 함수 실행 후 ---
여기서 가동성을 위해 @ 기호를 사용해 표기하면, 아래와 같이 나타낼 수 있습니다.
@my_decorator
def say_hello():
print("안녕하세요!")
say_hello()
# 출력하면 :
# --- 함수 실행 전 ---
# 안녕하세요!
# --- 함수 실행 후 ---
@my_decorator라고 적는 순간, 파이썬은 자동으로 say_hello = my_decorator(say_hello)를 실행해줍니다.
함수 인자를 전달하기
만약 이렇게 함수가 인자를 받을 때, 데코레이터가 이 인자도 사용해야 하는 경우도 있을 것입니다.
def say_hello(name):
print(f"{name}님, 안녕하세요!")
이럴 때는 wrapper에게도 똑같은 인자를 전달해주면 됩니다. 보통 모든 종류의 함수에 대응하기 위해, *args와 **kwargs를 사용하는 편입니다.
def my_decorator(func):
def wrapper(*args, **kwargs):
print("--- 함수 실행 전 ---")
func(*args, **kwargs) # wrapper의 인자를 그대로 넘겨주면 됩니다.
print("--- 함수 실행 후 ---")
return wrapper
중첩 데코레이터
하나의 함수에 여러 개의 데코레이터를 붙일 수도 있습니다. 이때는 함수와 가까운 쪽부터 순차적으로(아래에서 위로) 적용됩니다.
@decorator_A
@decorator_B
def say_hello(name):
print(f"{name}님, 안녕하세요!")
# decorator_A(decorator_B(say_hello))과 같습니다.
예시1 - Flask
Python 웹 프레임워크 라이브러리인 Flask에서 routing을 위해 데코레이터를 사용합니다. 여기서 app.route() 데코레이터는 인자로 받은 URL 경로(여기서는 root '/')와 함수(get_users)를 연결합니다.
import Flask
app = Flask(__name__)
@app.route('/', methods=['GET'])
def get_users():
# 서버 주소로 GET 요청을 보낼 때 실행할 함수 내용
예시2 - Modal
서버리스 컴퓨팅 라이브러리 Modal에서 원격으로 실행할 함수를 지정하기 위해 데코레이터를 사용합니다. @app.function() 데코레이터를 통해 지정할 수 있고, @app.local_entrypoint() 데코레이터를 통해 app을 로컬에서 실행할 때 제일 먼저 실행할 함수를 지정할 수 있습니다.
import modal
app = modal.App("example-get-started")
@app.function()
def square(x):
print("This code is running on a remote worker!")
return x**2
@app.local_entrypoint()
def main():
print("the square is", square.remote(42))
데코레이터는 기존 코드를 건드리지 않고 기능을 확장하기 위해 겉포장지(wrapper)만 갈아 끼우는 것입니다. 재사용성이 높아지기 때문에, 코드를 깔끔하게 작성할 수 있습니다.
'Language > Python' 카테고리의 다른 글
| [Python] Syntax | 04. import (0) | 2026.02.17 |
|---|---|
| [Python] Event Loop (0) | 2026.02.16 |
| [Python] Library | 08. asyncio (0) | 2026.02.15 |
| [Python] Closure (0) | 2026.02.15 |
| [Python] Garbage Collection (0) | 2026.02.15 |