💻
프로그래밍
데코레이터
Decorator
함수나 클래스의 동작을 수정하는 래퍼. Python의 @decorator 문법. 메타프로그래밍에 활용.
Decorator
함수나 클래스의 동작을 수정하는 래퍼. Python의 @decorator 문법. 메타프로그래밍에 활용.
데코레이터는 함수나 클래스의 동작을 수정하거나 확장하는 디자인 패턴이자 문법입니다. Python에서는 @decorator 문법으로, JavaScript/TypeScript에서는 실험적 데코레이터 기능으로 널리 사용됩니다.
Python의 데코레이터는 본질적으로 함수를 인자로 받아 새 함수를 반환하는 고차 함수입니다. @log_time으로 함수를 꾸미면, 해당 함수 호출 전후에 시간을 측정하는 로직을 추가할 수 있습니다. 원본 함수 코드를 수정하지 않고도 기능을 확장하는 것입니다.
데코레이터는 횡단 관심사(cross-cutting concerns)를 처리하는 데 유용합니다. 로깅, 인증, 캐싱, 재시도 로직, 입력 검증 등 여러 함수에 공통으로 적용되는 기능을 데코레이터로 추출하면 코드 중복을 줄이고 관심사를 분리할 수 있습니다.
클래스 데코레이터는 클래스 전체를 감싸거나 수정합니다. Python의 @dataclass는 클래스에 __init__, __repr__ 등을 자동 생성합니다. 여러 데코레이터를 쌓아서 사용할 수 있으며, 아래에서 위로 적용됩니다.
import functools
import time
# 기본 데코레이터: 실행 시간 측정
def timer(func):
@functools.wraps(func) # 원본 함수의 메타데이터 보존
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 실행 시간: {end - start:.4f}초")
return result
return wrapper
# 인자를 받는 데코레이터
def retry(max_attempts=3):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"시도 {attempt + 1} 실패: {e}")
raise Exception(f"{max_attempts}번 시도 모두 실패")
return wrapper
return decorator
# 데코레이터 적용
@timer
@retry(max_attempts=3)
def fetch_data(url):
print(f"데이터 가져오는 중: {url}")
return {"data": "결과"}
# 클래스 메서드 데코레이터
class API:
@staticmethod
def require_auth(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
if not self.is_authenticated:
raise PermissionError("인증 필요")
return func(self, *args, **kwargs)
return wrapper
# 사용
result = fetch_data("https://api.example.com")