更改函数自身内部的属性



我正在尝试创建一个函数来记录它被调用的次数,我希望信息保留在函数本身中。我尝试像这样创建一个包装器:

def keep_count(f):
    f.count = 0
    @functools.wraps(f)
    def wrapped_f(*args, **kwargs):
        f(*args, **kwargs)
        f.count += 1
    return wrapped_f
@keep_count
def test_f(*args, **kwargs):
    print(args, kwargs)

我以为它会起作用,但我得到了一个AttributeError'function' object has no attribute 'count'.

我已经发现了问题:这是因为装饰器将我的test_f设置为等于wrapped_f(在keep_count装饰器内部定义),并且我正在增加原始f的数量,由于test_f引用了新功能,因此不再使用。

有没有办法在不进行太多黑客攻击的情况下做到这一点?

只需将属性设置为 wrapped_f 而不是 f 即可。 这要求您在定义函数后设置初始count,但这没什么大不了的:

def keep_count(f):
    @functools.wraps(f)
    def wrapped_f(*args, **kwargs):
        f(*args, **kwargs)
        wrapped_f.count += 1
    wrapped_f.count = 0
    return wrapped_f

然后使用您修饰的函数:

>>> test_f()
() {}
>>> test_f.count
1
>>> test_f()
() {}
>>> test_f.count
2

这是有效的wrapped_f因为 keep_count 中的局部变量。 由于wrapped_f的主体包含对wrapped_f的引用,它得到一个闭包,允许wrapped_f访问自身。

最新更新