PYTHON · 함수
데코레이터 — 함수를 감싸는 함수
데코레이터로 횡단 관심사(로깅, 캐싱, 인증 등)를 분리합니다.
함수중급decoratorfunctools.wrapstimerretrymemoize
핵심 설명
데코레이터로 횡단 관심사(로깅, 캐싱, 인증 등)를 분리합니다.
Python code
import functools
import time
# 기본 데코레이터 구조
def timer(func):
@functools.wraps(func) # 원본 메타데이터 보존
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__}: {elapsed:.4f}초")
return result
return wrapper
# 파라미터를 받는 데코레이터 (팩토리)
def retry(times: int = 3, delay: float = 0.5):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, times + 1):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"시도 {attempt}/{times} 실패: {e}")
if attempt < times:
time.sleep(delay)
raise RuntimeError(f"{times}번 모두 실패")
return wrapper
return decorator
# 클래스 기반 데코레이터
class Memoize:
def __init__(self, func):
self.func = func
self.cache = {}
functools.update_wrapper(self, func)
def __call__(self, *args):
if args not in self.cache:
self.cache[args] = self.func(*args)
return self.cache[args]
@timer
@retry(times=2, delay=0.1)
def fetch_data(url: str) -> str:
return f"data from {url}"
@Memoize
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
print(fib(35)) # 빠르게 계산학습 팁
@functools.wraps(func)를 반드시 붙이세요. 없으면 wrapper.__name__, wrapper.__doc__이 원본 함수의 것을 잃어버립니다.
주의할 점
데코레이터를 여러 개 쌓으면 아래에서 위로 적용됩니다. @A @B def f()는 A(B(f))입니다.
자주 묻는 질문
데코레이터 — 함수를 감싸는 함수란 무엇인가요?
데코레이터로 횡단 관심사(로깅, 캐싱, 인증 등)를 분리합니다.
데코레이터 — 함수를 감싸는 함수 학습 시 주의할 점은 무엇인가요?
데코레이터를 여러 개 쌓으면 아래에서 위로 적용됩니다. @A @B def f() 는 A(B(f)) 입니다.
Continue Learning
Python 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.