Python - 装饰器操作目标函数的属性
Python - decorator manipulating attributes of target functions
我的目标是提出一个装饰器,它可以接受具有任意数量参数的函数并更改目标函数的属性。一个例子,我需要目标函数中的一个属性,它包含以秒为单位的执行长度。
我试图利用 functool 的 wraps
方法来保留属性,但没有成功。它似乎只保留 __doc__
和 __name__
等初始属性,但我无法为不存在的属性分配新值。
我知道我可以在返回它之前将持续时间属性分配给 wrapper
,而不是 func
。但这仅适用于我们不必计算 func 内部发生的情况的情况,就像我的情况一样。所以,这是我的代码:
import time
from functools import wraps
def my_dec(param):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
func.duration = time.time() - start
return rs
wrapper.a = 'a'
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.duration)
分配给 wrapper.duration
有效...
import time
from functools import wraps
def my_dec(param):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
wrapper.duration = time.time() - start
return rs
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.duration)
替代答案,如果您想避免在其自己的定义中引用 wrapper
函数:
import time
from functools import wraps
def my_dec(param):
def decorator(func):
durations = []
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
durations.append(time.time() - start)
return rs
wrapper.durations = durations
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.durations)
我的目标是提出一个装饰器,它可以接受具有任意数量参数的函数并更改目标函数的属性。一个例子,我需要目标函数中的一个属性,它包含以秒为单位的执行长度。
我试图利用 functool 的 wraps
方法来保留属性,但没有成功。它似乎只保留 __doc__
和 __name__
等初始属性,但我无法为不存在的属性分配新值。
我知道我可以在返回它之前将持续时间属性分配给 wrapper
,而不是 func
。但这仅适用于我们不必计算 func 内部发生的情况的情况,就像我的情况一样。所以,这是我的代码:
import time
from functools import wraps
def my_dec(param):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
func.duration = time.time() - start
return rs
wrapper.a = 'a'
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.duration)
分配给 wrapper.duration
有效...
import time
from functools import wraps
def my_dec(param):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
wrapper.duration = time.time() - start
return rs
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.duration)
替代答案,如果您想避免在其自己的定义中引用 wrapper
函数:
import time
from functools import wraps
def my_dec(param):
def decorator(func):
durations = []
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
rs = func(*args, **kwargs)
durations.append(time.time() - start)
return rs
wrapper.durations = durations
return wrapper
return decorator
@my_dec('Dec param')
def target_func(x):
return x.upper()
target_func('test value')
print(target_func.durations)