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