Updated Feb 13, 2026
데코레이터란 무엇인가?
데코레이터(Decorator)는 함수나 클래스를 수정하지 않고 기능을 추가하거나 변경할 수 있는 파이썬의 강력한 문법입니다. @ 기호로 시작하는 이 패턴은 코드의 재사용성을 높이고, 중복을 제거하며, 가독성을 향상시킵니다.
데코레이터는 본질적으로 “함수를 받아서 함수를 반환하는 함수”입니다.
기본 구조를 살펴보겠습니다.
def my_decorator(func):
def wrapper(*args, **kwargs):
print("함수 실행 전")
result = func(*args, **kwargs)
print("함수 실행 후")
return result
return wrapper
@my_decorator
def say_hello(name):
print(f"안녕하세요, {name}님!")
say_hello("김철수")
# 출력:
# 함수 실행 전
# 안녕하세요, 김철수님!
# 함수 실행 후
내장 데코레이터 마스터하기
파이썬은 실무에서 자주 사용하는 내장 데코레이터를 제공합니다.
@property: 속성처럼 사용하는 메서드
@property는 메서드를 속성처럼 접근할 수 있게 만들어 캡슐화를 구현합니다.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("반지름은 양수여야 합니다")
self._radius = value
@property
def area(self):
return 3.14159 * self._radius ** 2
c = Circle(5)
print(c.radius) # 5 (메서드지만 속성처럼 접근)
print(c.area) # 78.53975
c.radius = 10 # setter 호출
@staticmethod와 @classmethod
두 데코레이터의 차이를 명확히 이해하는 것이 중요합니다.
| 데코레이터 | 첫 번째 인자 | 용도 | 인스턴스 접근 | 클래스 접근 |
|---|---|---|---|---|
@staticmethod |
없음 | 유틸리티 함수 | 불가 | 불가 |
@classmethod |
cls | 팩토리 메서드, 클래스 변수 접근 | 불가 | 가능 |
class DateParser:
default_format = "%Y-%m-%d"
@staticmethod
def is_valid_date(date_string):
# 단순 유틸리티 함수
return len(date_string) == 10 and date_string[4] == '-'
@classmethod
def from_timestamp(cls, timestamp):
# 클래스 생성자 역할 (팩토리 메서드)
from datetime import datetime
return cls(datetime.fromtimestamp(timestamp))
@functools.wraps: 메타데이터 보존
데코레이터를 만들 때 원본 함수의 메타데이터를 보존하려면 @wraps를 사용해야 합니다.
from functools import wraps
def retry(max_attempts=3):
def decorator(func):
@wraps(func) # 원본 함수의 __name__, __doc__ 보존
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts - 1:
raise
print(f"재시도 {attempt + 1}/{max_attempts}")
return wrapper
return decorator
Enjoying this article? Get more like it delivered to your inbox. Subscribe to the newsletter
실전 커스텀 데코레이터
성능 측정 데코레이터
import time
from functools import wraps
def measure_time(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - start
print(f"{func.__name__} 실행 시간: {elapsed:.4f}초")
return result
return wrapper
@measure_time
def slow_function():
time.sleep(2)
return "완료"
권한 검사 데코레이터
웹 애플리케이션에서 자주 사용하는 패턴입니다.
def require_auth(permission):
def decorator(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not hasattr(user, 'permissions'):
raise PermissionError("권한 정보가 없습니다")
if permission not in user.permissions:
raise PermissionError(f"{permission} 권한이 필요합니다")
return func(user, *args, **kwargs)
return wrapper
return decorator
@require_auth('admin')
def delete_user(user, target_id):
print(f"사용자 {target_id} 삭제")
캐싱 데코레이터
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(100)) # 즉시 계산 (캐시 덕분)
클래스 데코레이터
함수뿐만 아니라 클래스 전체를 데코레이트할 수도 있습니다.
def singleton(cls):
instances = {}
@wraps(cls)
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class DatabaseConnection:
def __init__(self):
print("DB 연결 생성")
db1 = DatabaseConnection() # "DB 연결 생성" 출력
db2 = DatabaseConnection() # 출력 없음 (같은 인스턴스)
print(db1 is db2) # True
데코레이터 체이닝
여러 데코레이터를 동시에 적용할 수 있습니다. 아래에서 위로 적용됩니다.
@retry(max_attempts=3)
@measure_time
@require_auth('user')
def api_call(user, endpoint):
# 실제 실행 순서:
# 1. require_auth 검사
# 2. measure_time으로 시간 측정 시작
# 3. retry로 최대 3번 재시도
pass
데코레이터 활용 시 주의사항
@wraps항상 사용: 디버깅과 문서화를 위해 필수- 과도한 중첩 피하기: 3개 이상 체이닝은 가독성 저하
- 상태 관리 주의: 데코레이터 내부 변수는 모든 호출에서 공유됨
- 인자가 있는 데코레이터: 3중 중첩 함수 구조 필요 (데코레이터 팩토리 → 데코레이터 → wrapper)
마무리
데코레이터는 파이썬의 핵심 기능으로, 코드의 재사용성, 가독성, 유지보수성을 극대화합니다. 핵심 포인트를 정리하면:
@property로 깔끔한 인터페이스 설계@staticmethod/@classmethod로 명확한 책임 분리@wraps로 메타데이터 보존 필수- 커스텀 데코레이터로 횡단 관심사(로깅, 캐싱, 권한) 분리
- 클래스 데코레이터로 싱글톤 등 패턴 구현
실무에서 반복되는 패턴을 발견하면 데코레이터로 추상화하는 습관을 들이세요. 처음엔 어렵게 느껴지지만, 익숙해지면 파이썬 코드의 품질이 한 단계 도약할 것입니다.
Did you find this helpful?
Your support keeps this blog running and ad-free content coming.
☕ Buy me a coffeeMost Popular Posts
- Custom Metaclass in Python: 43% Faster Validation (12,793 views)
- Python match-case: 7 Patterns That Beat if-elif Chains (947 views)
- YOLOv8 INT8 Quantization: 4x Faster on Jetson Orin (759 views)
- yfinance Alternatives 2026: 7 Free APIs Compared (649 views)
- PaddleOCR vs EasyOCR vs Tesseract: Why PaddleOCR Is Slower (549 views)