Python:Decorator
파라미터 전달 가능한 데코레이터 만드는 방법
Python에서 파라미터를 전달할 수 있는 데코레이터를 만들 때, 일반적으로 세 가지 레벨의 함수가 필요합니다:
- 데코레이터 생성 함수
- 실제 데코레이터 함수
- 그리고 래핑된 함수입니다.
각 함수에 적절한 심볼명을 추천하면 다음과 같습니다:
def decorator_with_params(param1, param2):
# 1. 데코레이터 생성 함수
def decorator(func):
# 2. 실제 데코레이터 함수
def wrapper(*args, **kwargs):
# 3. 래핑된 함수
print(f"데코레이터 파라미터: {param1}, {param2}")
print(f"함수 {func.__name__} 호출 전")
result = func(*args, **kwargs)
print(f"함수 {func.__name__} 호출 후")
return result
return wrapper
return decorator
심볼명 추천 기준
- 최상위 함수 (파라미터를 전달받는 생성 함수):
- 이름: decorator_with_params, create_decorator, decorator_factory, param_decorator
- 역할: 데코레이터의 동작 방식을 정의하는 파라미터를 받음.
- 이름: decorator, inner_decorator, wrap_function
- 역할: 데코레이터가 적용될 함수를 받아 내부에서 래핑 로직을 정의.
- 이름: wrapper, wrapped_func, decorated_func, inner_wrapper
- 역할: 실제 함수를 호출하기 전/후에 추가 동작을 실행.
def param_decorator(param1, param2):
def wrap_function(func):
def inner_wrapper(*args, **kwargs):
print(f"[DEBUG] Params: {param1}, {param2}")
print(f"[DEBUG] Before calling {func.__name__}")
result = func(*args, **kwargs)
print(f"[DEBUG] After calling {func.__name__}")
return result
return inner_wrapper
return wrap_function
# 데코레이터 사용
@param_decorator("Hello", "World")
def example_function(x, y):
print(f"Running example_function with {x} and {y}")
return x + y
# 함수 호출
result = example_function(10, 20)
print(f"Result: {result}")
Simple example
def measure_time(f):
def wrap(*args):
time1 = time.time()
ret = f(*args)
time2 = time.time()
print('%s function took %0.6f s' % (f.__name__, (time2-time1)))
return ret
return wrap
# ...
@measure_time
def test(a):
print('haha')
Decorators with Arguments
작동되는지 확인해봐야 한다.
def parametrized(dec):
def layer(*args, **kwargs):
def deco(f):
return dec(f, *args, **kwargs)
return deco
return layer
@parametrized
def elapsed_time_debug(func, name, logger):
def wrap(*args, **kwargs):
s = time.time()
func(*args, **kwargs)
e = time.time()
if logger:
logger.debug("[{}] {} detect time: {}".format(name, func.__name__, e-s))
return wrap
Documentation
functools 패키지의 의 wraps을 사용해야 한다.
from functools import wraps
# 파라메터 없는 데코레이터에도 @wraps 붙여주고
def decorator(func):
@wraps(func)
def decorator(*args, **kwargs):
print("%s %s" % (func.__name__, "before"))
result = func(*args, **kwargs)
print("%s %s" % (func.__name__, "after"))
return result
return decorator
# 파라메터 있는 데코레이터에도 @wraps 붙여주고
def decorator_with_param(param):
def wrapper(func):
@wraps(func)
def decorator(*args, **kwargs):
print(param)
print("%s %s" % (func.__name__, "before"))
result = func(*args, **kwargs)
print("%s %s" % (func.__name__ , "after"))
return result
return decorator
return wrapper
See also
Favorite site
- 파이썬 데코레이터 (decorator): 기초편
- [추천] 파이썬 - 데코레이터 (Decorator) 1
- Python — 데코레이터(decorator) 작성법
- [추천] Writing a Python decorator that can be called as a function or a callable
References
-
SchoolofWeb_-_Python_Decorator.pdf ↩