13. 데코레이터
데코레이터(Decorator)는 함수나 클래스의 기능을 수정하거나 확장하는 파이썬의 강력한 기능입니다.
학습 목표
이 챕터를 완료하면 다음을 할 수 있습니다:
- 함수 데코레이터 이해와 구현
- 클래스 데코레이터 활용
- 매개변수가 있는 데코레이터 작성
- 내장 데코레이터 완전 활용
- 실무 패턴으로 코드 품질 향상
핵심 개념(이론)
1) @는 문법 설탕이다: f = deco(f)
데코레이터 문법의 실체는 단순한 재할당입니다. @my_decorator를 함수 정의 위에 붙이는 것은, 함수 정의 직후에 say_goodbye = my_decorator(say_goodbye)를 실행하는 것과 완전히 동일합니다 (도입 배경과 문법 논의는 PEP 318 참조). 즉 데코레이터는 마법이 아니라 “함수를 받아 함수를 돌려주는 일급 함수(higher-order function)“이며, 이 디슈가링(desugaring) 한 줄만 이해하면 아래 모든 변형이 유도됩니다.
| |
2) 상태는 클로저(closure)에 저장된다
wrapper가 원본 func를 기억하는 이유는 클로저 때문입니다. my_decorator(func)가 반환하는 wrapper는 자신을 둘러싼 스코프의 func를 자유 변수(free variable)로 캡처하며, 이는 wrapper.__closure__에서 확인할 수 있습니다. 호출 횟수 세기처럼 값을 변경해야 하면 nonlocal 선언이 필요합니다 — 이것이 클래스 기반 데코레이터(self.count)와의 근본적 차이입니다.
3) 매개변수 있는 데코레이터 = 3중 중첩
@retry(max_attempts=3)처럼 인자를 받는 데코레이터는 구조가 다릅니다. retry(max_attempts=3)가 먼저 호출되어 데코레이터를 반환하고, 그 반환값이 함수에 적용됩니다. 즉 f = retry(max_attempts=3)(f) — “데코레이터를 만들어 주는 팩토리 → 데코레이터 → wrapper"의 3중 중첩입니다. 아래 실용 예제의 retry가 이 구조를 그대로 보여줍니다.
4) functools.wraps가 없으면 함수의 정체성이 사라진다
wrapper로 교체된 함수는 __name__이 "wrapper"가 되고 __doc__·시그니처 정보를 잃습니다. 이는 디버깅·문서 도구·직렬화(pickle)를 조용히 깨뜨립니다. @functools.wraps(func)는 원본의 __name__, __doc__, __module__ 등을 복사하고 __wrapped__ 속성으로 원본 접근 경로까지 남깁니다.
| |
흔한 오해/함정
표준 라이브러리를 두고 손수 만들지 말 것: 캐싱이 필요하면 먼저
functools.lru_cache(또는 3.9+의functools.cache)를 씁니다. 직접 구현(아래 프로젝트 2)은 TTL·커스텀 키·분산 캐시처럼lru_cache가 못 하는 요구가 있을 때만 정당화됩니다.1 2 3 4 5 6 7 8import functools @functools.lru_cache(maxsize=128) def fib(n): return n if n < 2 else fib(n - 1) + fib(n - 2) print(fib(100)) # 순식간에 계산 print(fib.cache_info()) # 히트/미스 통계 내장클래스 기반 데코레이터를 메서드에 붙이면
self가 사라진다:CountCalls같은 클래스 데코레이터는 함수를 인스턴스로 교체하는데, 일반 클래스 인스턴스는 함수와 달리 디스크립터 프로토콜(__get__)을 구현하지 않아 바운드 메서드가 만들어지지 않습니다. 인스턴스 메서드에는 클로저 기반 데코레이터를 쓰거나, 클래스 데코레이터에__get__을 구현해야 합니다.스택 순서는 아래에서 위로:
@a위에@b가 있으면f = b(a(f))입니다. 즉 함수에 가까운 데코레이터가 먼저 적용되고, 호출 시에는 바깥(위쪽) wrapper부터 실행됩니다. 로깅·트랜잭션·권한처럼 순서가 의미 있는 조합에서 자주 틀리는 지점입니다.
요약
@deco는f = deco(f)의 문법 설탕이고, 상태는 클로저가 담는다. 인자 있는 데코레이터는 3중 중첩(deco(args)(f))이다.functools.wraps는 선택이 아니라 기본값이다. 캐싱은lru_cache먼저, 직접 구현은 그것이 부족할 때만.
핵심 내용
데코레이터 기본 개념
함수를 인수로 받는 함수
| |
인수가 있는 함수 데코레이터
| |
실용적인 데코레이터들
로깅 데코레이터
| |
재시도 데코레이터
| |
클래스 데코레이터
클래스를 데코레이터로 사용
| |
클래스에 데코레이터 적용
| |
내장 데코레이터들
@property
| |
@staticmethod와 @classmethod
| |
실습 프로젝트
프로젝트 1: 성능 모니터링 시스템
| |
프로젝트 2: 캐시 시스템
| |
체크리스트
기본 데코레이터
- 함수 데코레이터 이해와 구현
- @functools.wraps 사용법
- *args, **kwargs 활용
- 반환값과 예외 처리
고급 데코레이터
- 매개변수가 있는 데코레이터
- 클래스 기반 데코레이터
- 클래스에 적용하는 데코레이터
- 데코레이터 체이닝
내장 데코레이터
- @property와 getter/setter
- @staticmethod, @classmethod
- @functools.lru_cache
- 기타 유용한 내장 데코레이터
실무 패턴
- 로깅과 모니터링
- 캐싱과 메모이제이션
- 재시도와 에러 처리
- 권한 검사와 검증
다음 단계
🎉 축하합니다! 파이썬 데코레이터를 마스터했습니다.
이제 14. 제너레이터와 이터레이터로 넘어가서 메모리 효율적인 데이터 처리 방법을 학습해봅시다.
💡 팁:
- 데코레이터는 함수의 시그니처를 보존하기 위해 @functools.wraps를 사용하세요
- 복잡한 로직은 클래스 기반 데코레이터로 구현하는 것이 좋습니다
- 성능이 중요한 경우 데코레이터의 오버헤드를 고려하세요
- 데코레이터 체이닝 시 실행 순서를 명확히 이해하세요
![Featured image of post [Python Master] 13. 데코레이터 - 클로저/캐싱/로깅 패턴](/post/python/python-decorators-closures-caching-logging-pattern-guide/wordcloud_hu_61f933a9da62b57.webp)
![[Python Master] 11. 표준 라이브러리 - os/pathlib/datetime/itertools](/post/python/python-standard-library-os-pathlib-datetime-itertools-guide/wordcloud_hu_8b9d7bf76eca62b.webp)
![[Python Master] 12. 정규표현식 - re 모듈/패턴 매칭/성능](/post/python/python-regex-re-module-pattern-matching-performance-guide/wordcloud_hu_d0ef0b630a5f1410.webp)
![[Python Master] 13. 데코레이터 - 클로저/캐싱/로깅 패턴](/post/python/python-decorators-closures-caching-logging-pattern-guide/wordcloud_hu_e72cd1b3e1c41e44.webp)
![[Python Master] 14. 제너레이터와 이터레이터 - 지연 평가/메모리 효율](/post/python/python-generators-iterators-lazy-evaluation-memory-guide/wordcloud_hu_264bfbf5ad27ac12.webp)
![[Python Master] 15. 컨텍스트 매니저 - with문/리소스 관리](/post/python/python-context-managers-with-statement-resource-cleanup-guide/wordcloud_hu_550dd86a541557eb.webp)
![[Python Master] 00. 왜 파이썬인가 - 학습 동기와 커리어 로드맵](/post/python/why-learn-python-motivation-career-roadmap-guide/wordcloud_hu_1fe3fd6ea793ec4c.webp)
![[Python Master] 01. 환경 설정 - 설치/가상환경/IDE 구성](/post/python/python-installation-venv-ide-setup-guide/wordcloud_hu_32a7d5c00c75a007.webp)
![[Python Master] 02. 기본 문법 - 변수/타입/연산자/입출력](/post/python/python-basic-syntax-variables-types-operators-io-guide/wordcloud_hu_4751e8ce5b326128.webp)
![[Python Master] 03. 제어 구조 - 조건문/반복문/break-continue](/post/python/python-control-flow-if-for-while-break-continue-guide/wordcloud_hu_42d911257a3aa072.webp)
![[Python Master] 04. 함수 - 매개변수/스코프/람다/클로저](/post/python/python-functions-parameters-scope-lambda-closure-guide/wordcloud_hu_c12519d8eb565b61.webp)