[Python] 데코레이터(Decorator) - @문법, functools.wraps
by 우와한개발자
1. 데코레이터란?
- '장식하는 사람'이라는 뜻처럼, 함수를 직접 수정하지 않고 기능을 추가할 때 사용
- 기존 함수를 입력받아 기능이 추가된 새로운 함수 객체로 만들어주는 역할
- AOP(관점 지향 프로그래밍)의 파이썬 구현 방식
- 로깅, 인증, 실행시간 측정 등 공통 기능을 분리할 때 활용
2. 기본 구조
def my_decorator(func): # 1. 원본 함수를 인자로 받음
def wrapper(): # 2. 기능을 추가한 새 함수 정의
print('실행 전')
func() # 3. 원본 함수 호출
print('실행 후')
return wrapper # 4. wrapper 함수 반환 (호출 X)
@my_decorator
def hello():
print('hello')
hello()
# 실행 전
# hello
# 실행 후
3. 데코레이터 적용 방법
1) 직접 할당
hello = my_decorator(hello) # hello 변수를 기능이 추가된 함수로 대체
hello()
# 실행 전
# hello
# 실행 후
2) @ 문법
- hello = my_decorator(hello) 와 완전히 동일한 동작
- 함수 정의 위에 @데코레이터함수 를 붙여주면 됨
@my_decorator
def hello():
print('hello')
hello()
# 실행 전
# hello
# 실행 후
4. 인자가 있는 함수에 적용
- *args, **kwargs 로 인자를 그대로 전달
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('실행 전')
result = func(*args, **kwargs) # 인자 그대로 전달
print('실행 후')
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
print(add(1, 2))
# 실행 전
# 실행 후
# 3
5. 데코레이터 여러 개 적용
- 위에서 아래 순서로 감싸고, 실행은 위에서부터
def decorator_a(func):
def wrapper():
print('A 실행 전')
func()
print('A 실행 후')
return wrapper
def decorator_b(func):
def wrapper():
print('B 실행 전')
func()
print('B 실행 후')
return wrapper
@decorator_a
@decorator_b
def hello():
print('hello')
hello()
# A 실행 전
# B 실행 전
# hello
# B 실행 후
# A 실행 후
6. functools.wraps
- 데코레이터 적용 시 함수 이름과 docstring 이 wrapper로 덮어씌워지는 문제 방지
- 원래 @my_decorator 를 붙이는 순간 hello = my_decorator(hello) 가 되고, 결국 hello 는 wrapper 함수가 되어버리기 때문에 이름도 wrapper가되고 docstring도 None 이 되는데 그걸 방지해줌
from functools import wraps
def my_decorator(func):
@wraps(func) # ← func의 이름, docstring을 wrapper에 복사
def wrapper():
print('실행 전')
func()
print('실행 후')
return wrapper
@my_decorator
def hello():
"""인사 함수"""
print('hello')
print(hello.__name__) # hello
print(hello.__doc__) # 인사 함수
7. 실전 활용 예시
1) 실행시간 측정
import time
from functools import wraps
def timer(func):
@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
@timer
def slow_function():
time.sleep(1)
slow_function()
# slow_function 실행시간: 1.0012초
2) 로그 출력
from functools import wraps
def logger(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f'[LOG] {func.__name__} 호출 - args: {args}, kwargs: {kwargs}')
return func(*args, **kwargs)
return wrapper
@logger
def add(a, b):
return a + b
add(1, 2)
# [LOG] add 호출 - args: (1, 2), kwargs: {}
'언어 > Python' 카테고리의 다른 글
| [Python] pdfplumber로 PDF 텍스트 추출하기 (0) | 2026.04.29 |
|---|---|
| [Python] IMAP으로 Gmail 메일 가져오기 - 메일 검색, 데이터 추출, 첨부파일 다운로드 (0) | 2026.04.29 |
| [Python] pandas로 Oracle 데이터 읽기 - read_sql, DataFrame (0) | 2026.04.19 |
| [Python] 오라클 DB 연결 - pip install oracledb / Connect, Cursor, Row 객체 (0) | 2026.04.19 |
| [Python] JSON 파일 읽고 쓰기 - json.dump/load, HDF5, 파일 형식 비교 (0) | 2026.04.19 |
블로그의 정보
우와한개발자 님의 블로그
우와한개발자