我试图创建一个函数来记录它被调用的次数,我希望信息保留在函数本身内部。 我尝试创建一个这样的包装器:
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
引用了新函数,因此不再使用该计数。
有没有办法在没有太多黑客攻击的情况下做到这一点?
答案 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_f
是keep_count
内的局部变量。由于wrapped_f
的正文包含对wrapped_f
的引用,因此它会获得一个允许wrapped_f
访问自身的闭包。