파이썬에서 데코레이터(Decorator)는 기존 함수의 코드를 수정하지 않고도 기능을 확장하거나 변경할 수 있게 해주는 강력한 도구입니다. 함수를 인자로 받아 새로운 기능을 추가한 함수를 반환하는 고차 함수(Higher-order function)의 일종입니다.
가장 흔한 활용 사례 중 하나는 로그를 출력할 때 자동으로 타임스탬프를 추가하는 것입니다. 이를 통해 비즈니스 로직과 부가적인 로깅 로직을 깔끔하게 분리할 수 있습니다.
먼저, 현재 시간을 특정 포맷의 문자열로 반환하는 보조 함수를 정의합니다.
import datetime
def get_formatted_time():
now = datetime.datetime.now()
return now.strftime("%Y-%m-%d %H:%M:%S")
이제 데코레이터를 작성해 보겠습니다. 데코레이터는 내부 함수(wrapper)를 정의하고 이를 반환하는 구조를 가집니다. 원본 함수가 인자를 전달받을 수 있도록
*args와
**kwargs를 사용하는 것이 핵심입니다.
def log_with_timestamp(target_func):
def wrapper(*args, **kwargs):
# 현재 시간 생성
time_prefix = get_formatted_time()
# 원본 함수 실행
message = target_func(*args, **kwargs)
# 시간 정보와 메시지 결합
return f"[{time_prefix}] {message}"
return wrapper
위 코드에서
log_with_timestamp는 데코레이터 역할을 하며, 실제 실행되는 로직은
wrapper 함수 안에 포함됩니다.
target_func는 데코레이터가 적용될 원본 함수를 가리킵니다.
이제 이 데코레이터를 실제 로그 기록 함수에 적용해 보겠습니다. 파이썬에서는
@ 심볼을 사용하여 간결하게 데코레이터를 호출할 수 있습니다.
@log_with_timestamp
def create_log_entry(content):
return content
# 함수 호출 테스트
log_data = "시스템 점검을 시작합니다."
result = create_log_entry(log_data)
print(result)
작동 원리를 살펴보면,
create_log_entry 함수가 호출될 때 파이썬 인터프리터는 이를
log_with_timestamp(create_log_entry)로 변환하여 처리합니다. 결과적으로 다음과 같은 형태의 출력을 얻을 수 있습니다.
[2024-05-22 14:30:05] 시스템 점검을 시작합니다.
만약 데코레이터를 사용하지 않는다면 모든 로그 출력 함수마다 시간 생성 로직을 중복해서 작성해야 하지만, 데코레이터를 활용하면 단 한 줄의 선언만으로 공통 기능을 재사용할 수 있습니다.
주의할 점은 데코레이터 내부의
wrapper 함수가 원본 함수의 인자 구조를 그대로 받아낼 수 있어야 한다는 것입니다.
*args와
**kwargs를 활용하면 어떤 형태의 인자를 가진 함수라도 유연하게 대응할 수 있는 범용 데코레이터를 만들 수 있습니다.