我正在尝试创建一个函数来记录它被调用的次数,我希望信息保留在函数本身中。我尝试像这样创建一个包装器:
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
访问自身。