在函数体内更改函数的属性?
Change an attribute of a function inside its own body?
我正在尝试创建一个函数来记录它被调用的次数,我希望信息保留在函数本身中。
我尝试像这样创建一个包装器:
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
访问自身的闭包。
我正在尝试创建一个函数来记录它被调用的次数,我希望信息保留在函数本身中。 我尝试像这样创建一个包装器:
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
访问自身的闭包。