반응형
이 글은 파이썬 데코레이터에 대한 이해를 돕기 위해 작성되었습니다. 데코레이터의 기본 개념, 사용법, 그리고 실용적인 예시들을 통해 함수의 행동을 수정하고 확장하는 방법을 설명합니다. 이를 통해 코드의 가독성을 높이고 유지보수를 쉽게 할 수 있도록 하는 것이 목적입니다.
파이썬 데코레이터
데코레이터는 함수의 역할을 수정하는 특이한 방법인데요, 이러한 방법을 통해 코드를 간결하고 유지보수가 쉽게 만들 수 있습니다. 데코레이터는 다른 함수를 인수로 받아 "래핑(wrap)"하여 그 함수의 기능을 확장하거나 수정할 수 있습니다.
- 예시 코드:
def decorator_func(original_func):
def wrapper_func(*args, **kwargs):
print(f"래핑 전: {args}, {kwargs}")
result = original_func(*args, **kwargs)
print(f"래핑 후: {result}")
return result
return wrapper_func
@decorator_func
def display():
print("display 함수가 실행되었습니다.")
display()
- 출력:
래핑 전: (), {}
display 함수가 실행되었습니다.
래핑 후: None
이 예시 코드에서 `display` 함수는 `decorator_func`로 데코레이팅되었습니다. 실행할 때마다 `display` 함수 전후에 추가 코드가 실행되는 것을 볼 수 있습니다.
파이썬 데코레이터 사용 방법
- 데코레이터 함수: 다른 함수를 인수로 받아 래핑 하는 함수입니다.
- 래퍼(Wrapper) 함수: 원래 함수를 감싸고 추가 기능을 제공하는 함수입니다.
- 원래 함수: 데코레이터가 래핑하는 함수입니다.
- 데코레이터는 `@` 문법을 통해 적용됩니다. 이렇게 하면 함수의 이름이 래퍼 함수로 바인딩됩니다.
사례 1. 로깅 데코레이터
from datetime import datetime
def log_decorator(original_func):
def wrapper_func(*args, **kwargs):
result = original_func(*args, **kwargs)
print(f"{datetime.now()}: {original_func.__name__} 함수가 실행되었습니다. 결과: {result}")
return result
return wrapper_func
@log_decorator
def add_numbers(a, b):
return a + b
result = add_numbers(3, 5)
print(result)
- 이 데코레이터는 함수가 실행될 때마다 시간과 함수 이름, 결과를 로깅합니다. 디버깅이나 실행 추적에 유용합니다.
사례 2. 캐싱 데코레이터
cache = {}
def cache_decorator(original_func):
def wrapper_func(*args, **kwargs):
key = str(args) + str(kwargs)
if key in cache:
print(f"캐시에서 값을 가져왔습니다: {cache[key]}")
return cache[key]
else:
result = original_func(*args, **kwargs)
cache[key] = result
print(f"캐시에 값을 저장했습니다: {result}")
return result
return wrapper_func
@cache_decorator
def expensive_func(a, b):
print("계산 중...")
return a ** b
result1 = expensive_func(2, 3)
result2 = expensive_func(2, 3) # 캐싱된 값을 사용합니다.
- 이 데코레이터는 함수의 입력과 출력을 캐싱합니다. 같은 입력이 주어지면 캐시 된 결과를 반환하므로 불필요한 계산을 피할 수 있습니다.
사례 3. 타임아웃 데코레이터
import signal
from functools import wraps
class TimeoutError(Exception):
pass
def timeout_decorator(timeout_secs):
def decorator(original_func):
@wraps(original_func)
def wrapper_func(*args, **kwargs):
def handler(signum, frame):
raise TimeoutError(f"{original_func.__name__} 함수가 {timeout_secs}초 동안 실행되지 않아 중단되었습니다.")
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout_secs)
try:
result = original_func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wrapper_func
return decorator
@timeout_decorator(5)
def slow_func(n):
import time
time.sleep(n)
return n
try:
result = slow_func(3)
print(f"결과: {result}")
except TimeoutError as e:
print(e)
try:
result = slow_func(10)
print(f"결과: {result}")
except TimeoutError as e:
print(e)
- 이 데코레이터는 함수 실행 시간을 제한합니다. 지정된 시간이 지나면 `TimeoutError`를 발생시켜 함수 실행을 중단합니다.
이러한 실용적인 예시들을 통해 데코레이터가 코드를 더 유연하고 재사용 가능하게 만들어주는 것을 알 수 있습니다.
사용 시 주의해야 할 사항으로는:
- 데코레이터는 중첩될 수 있습니다. 여러 개의 데코레이터를 함수에 적용할 수 있습니다.
- 래퍼 함수 내에서 원래 함수의 메타데이터(docstring, name, annotations 등)에 접근하려면 `functools.wraps` 데코레이터를 사용하는 것이 좋습니다.
데코레이터는 파이썬의 강력한 기능 중 하나입니다. 이 가이드북을 통해 데코레이터의 기본 개념과 다양한 활용 방법을 익혔으니 직접 연습해 보며 이해도를 높이는 것이 좋습니다.
반응형
'프로그래밍 언어 > Python' 카테고리의 다른 글
파이썬 입문자를 위한 웹 스크래핑, BeautifulSoup, Requests 라이브러리 - Python 기초 #15 (0) | 2024.05.27 |
---|---|
파이썬 에러 및 예외 처리 완벽 가이드: 초보자를 위한 핵심 개념과 실전 예시 - Python 기초 #14 (0) | 2024.05.25 |
Python 상속 코드 재사용성 극대화를 위한 객체 지향 프로그래밍 가이드 - Python 기초 #12 (0) | 2024.05.23 |
객체 지향 프로그래밍의 핵심, 파이썬 메서드 이해하기 - Python 기초 #11 (0) | 2024.05.22 |
파이썬 매직 메서드 완벽 가이드, 클래스 기능 확장하기 - Python 기초 #10 (0) | 2024.05.21 |