Python 데코레이터 마법 발휘!
Lukas Schneider
DevOps Engineer · Leapcell

Python 데코레이터: 강력한 프로그래밍 도구
Python 데코레이터는 프로그래머가 원래 함수 정의를 수정하지 않고도 함수에 추가 기능을 추가할 수 있도록 하는 매우 강력한 도구입니다. 이 기능은 코드 유지 관리 및 확장을 더 쉽게 만들고 코드 가독성 및 재사용성을 향상시킵니다. 데코레이터는 로깅, 성능 테스트, 트랜잭션 처리, 캐싱 및 권한 확인과 같은 영역을 포괄하는 광범위한 응용 시나리오를 가지고 있습니다. 이 기사에서는 Python에서 데코레이터를 능숙하게 사용하여 몇 가지 구체적인 예를 통해 실제 문제를 해결하는 방법을 자세히 소개합니다.
로깅
소프트웨어 개발 프로세스에서 로깅은 매우 중요한 작업입니다. 개발자가 코드의 실행 흐름을 추적하고, 오류를 해결하고, 시스템의 실행 상태를 모니터링하는 데 도움이 됩니다. 데코레이터를 사용하면 각 함수에 로깅 코드를 수동으로 추가하지 않고도 함수에 로깅 기능을 쉽게 추가할 수 있습니다. 이를 통해 코드 중복이 줄어들 뿐만 아니라 코드 구조가 더 명확해집니다.
import logging def log_decorator(func): def wrapper(*args, **kwargs): logging.info(f"Running '{func.__name__}' with arguments {args} and {kwargs}") return func(*args, **kwargs) return wrapper @log_decorator def say_hello(name): print(f"Hello, {name}!") say_hello("Alice")
코드 설명
위의 코드는 log_decorator라는 데코레이터 함수를 정의합니다. 이 함수는 함수 func를 매개변수로 받아 새 함수 wrapper를 반환합니다. wrapper 함수에서 먼저 logging.info를 사용하여 호출된 함수의 이름과 전달된 매개변수를 기록한 다음 원래 함수 func를 호출하고 실행 결과를 반환합니다. say_hello 함수 정의 위에 @log_decorator를 배치하면 say_hello 함수가 이 데코레이터로 데코레이션됩니다. say_hello 함수가 호출될 때마다 로깅이 자동으로 기록됩니다.
성능 테스트
성능을 최적화할 때 성능 병목 현상을 식별하고 최적화하기 위해 코드의 실행 시간을 측정해야 하는 경우가 많습니다. 데코레이터는 이 프로세스를 자동화하고 표준화하여 다양한 함수의 성능을 더 쉽게 비교하고 분석할 수 있도록 합니다.
import time def timing_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} took {end_time - start_time:.4f} seconds to run.") return result return wrapper @timing_decorator def slow_function(delay_time): time.sleep(delay_time) slow_function(2)
코드 설명
이 코드는 timing_decorator 데코레이터를 정의합니다. wrapper 함수 내부에서 time.time()은 함수 실행 전후의 시간을 기록하는 데 사용됩니다. 둘 사이의 차이를 계산하여 함수의 실행 시간을 얻어 출력합니다. 이러한 방식으로 timing_decorator로 데코레이션된 함수가 호출될 때마다 함수의 실행 시간이 자동으로 출력됩니다.
결과 캐싱
특히 고정된 입력 및 출력이 있는 함수의 경우 시간이 오래 걸리는 계산의 경우 동일한 결과를 다시 계산하면 많은 시간과 리소스가 낭비됩니다. 데코레이터를 사용하여 결과를 캐싱하면 성능을 크게 향상시키고 불필요한 반복 계산을 피할 수 있습니다.
from functools import lru_cache @lru_cache(maxsize=32) def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) print(fib(10))
코드 설명
여기서는 functools 모듈의 lru_cache 데코레이터가 사용됩니다. lru_cache는 Least Recently Used 캐시의 약자로, 함수의 호출 결과를 자동으로 캐싱합니다. 동일한 매개변수가 다시 호출되면 함수를 다시 실행하는 대신 캐시된 결과가 직접 반환됩니다. maxsize 매개변수는 캐시의 최대 용량을 지정합니다. 캐시가 이 용량에 도달하면 가장 최근에 사용되지 않은 캐시 항목이 제거됩니다.
권한 확인
웹 개발에서는 특정 작업을 수행할 수 있는 권한이 있는 사용자만 있는지 확인하기 위해 사용자의 권한을 확인해야 하는 경우가 많습니다. 데코레이터는 이 기능을 우아하게 구현하고 권한 확인 논리를 비즈니스 논리와 분리하고 코드 유지 관리성을 향상시키는 데 도움이 될 수 있습니다.
from functools import wraps def permission_required(permission): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): user_permission = kwargs.get('user_permission') if user_permission!= permission: raise Exception("Permission denied") return func(*args, **kwargs) return wrapper return decorator @permission_required('admin') def delete_user(user_id, user_permission): print(f"User {user_id} has been deleted.") delete_user(1, user_permission='admin') # Success delete_user(1, user_permission='guest') # Exception: Permission denied
코드 설명
permission_required는 필요한 권한을 나타내는 permission 매개변수를 사용하는 데코레이터 팩토리 함수입니다. 내부 decorator 함수는 함수 func를 매개변수로 받아 새 wrapper 함수를 반환합니다. wrapper 함수에서는 user_permission이 kwargs에 포함되어 있는지, 이 권한이 필요한 permission과 일치하는지 확인합니다. 그렇지 않으면 Permission denied 예외가 발생합니다. 그렇지 않으면 원래 함수 func가 실행됩니다.
매개변수 확인
데코레이터를 사용하여 함수 매개변수가 특정 조건을 충족하는지 확인할 수도 있습니다. 이렇게 하면 함수가 실행되기 전에 매개변수 오류를 감지하고 함수 내부에서 불필요한 작업을 피하고 코드의 견고성을 향상시킬 수 있습니다.
from functools import wraps def type_check(correct_type): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): if not all([isinstance(arg, correct_type) for arg in args])): raise ValueError("Incorrect argument type") return func(*args, **kwargs) return wrapper return decorator @type_check(str) def string_repeat(string, times): return string * times print(string_repeat("hello", 3)) # Works string_repeat("hello", "3") # Raises ValueError
코드 설명
type_check 데코레이터 팩토리 함수는 예상되는 매개변수 유형을 나타내는 correct_type 매개변수를 사용합니다. wrapper 함수에서는 isinstance 함수를 사용하여 모든 위치 인수가 지정된 유형인지 확인합니다. 인수의 유형이 일치하지 않으면 ValueError 예외가 발생합니다. 그렇지 않으면 원래 함수 func가 실행됩니다.
결론
데코레이터는 함수의 기능을 향상시키는 효율적이고 우아한 방법을 제공합니다. 최소한의 코드 변경으로 기능 확장을 달성하는 데 도움이 될 수 있습니다. 이 기사의 예제를 통해 실제 개발에서 데코레이터의 강력한 기능과 유연한 응용 프로그램을 볼 수 있습니다. 데코레이터를 올바르게 사용하면 코드를 더 간결하고 유지 관리하기 쉽고 코드 가독성과 유용성을 향상시킬 수 있습니다. 일상적인 프로그래밍에서는 특정 요구 사항에 따라 데코레이터를 유연하게 사용하여 코드 구조를 최적화하고 개발 효율성을 향상시킬 수 있습니다.
Leapcell: Python 앱 호스팅을 위한 최고의 서버리스 플랫폼

마지막으로, Python 서비스 배포를 위한 최고의 플랫폼을 추천합니다: Leapcell
1. 다중 언어 지원
- JavaScript, Python, Go 또는 Rust로 개발하세요.
2. 무제한 프로젝트를 무료로 배포합니다
- 사용량에 대해서만 지불하세요. 요청도 없고 요금도 없습니다.
3. 최고의 비용 효율성
- 유휴 요금 없이 사용량에 따라 지불합니다.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
4. 간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
5. 간편한 확장성과 높은 성능
- 고도의 동시성을 쉽게 처리할 수 있도록 자동 확장.
- 운영 오버헤드가 전혀 없습니다. 구축에만 집중하세요.

Leapcell Twitter: https://x.com/LeapcellHQ

