在自己的体内更改函数的属性?

时间:2015-01-12 19:45:54

标签: python function python-3.x decorator

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

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装饰器内定义),而我是' m增加原始f的计数,由于test_f引用了新函数,因此不再使用该计数。

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

1 个答案:

答案 0 :(得分:9)

只需在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_fkeep_count内的局部变量。由于wrapped_f的正文包含对wrapped_f的引用,因此它会获得一个允许wrapped_f访问自身的闭包。