Python-装饰器操作目标函数的属性

问题描述 投票:2回答:2

我的目标是提出一个装饰器,该装饰器将接受具有任意数量参数的函数并更改目标函数的属性。一个示例,我需要目标函数中的一个属性,其中包含执行时间(以秒为单位)。我试图利用functool的wraps方法来保存属性,但是没有成功。它似乎只保留诸如__doc____name__之类的初始属性,但是我无法为不存在的属性分配新值。我知道我可以在返回wrapper之前将duration属性分配给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)
python python-decorators
2个回答
2
投票

分配给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)

0
投票

替代答案,如果要避免在其自己的定义内引用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)
© www.soinside.com 2019 - 2024. All rights reserved.