在其自己的内部更改函数的属性? [英] 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.wrap(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
来访问自己。
I'm attempting to create a function that keeps count of the times it has been called, and I want the information to stay inside the function itself. I tried creating a wrapper like so:
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)
I thought it'd work, but I got an AttributeError
saying 'function' object has no attribute 'count'
.
I already figured the problem: It's because the decorator sets my test_f
to equal to the wrapped_f
(defined inside the keep_count
decorator), and I'm increasing the count of the original f
, which is no longer used since test_f
refers to the new function.
Is there a way to do this without too much of hacking?
Just set the attribute on wrapped_f
instead of f
. This requires you to set the initial count
after defining the function, but that's no big deal:
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
Then with your decorated function:
>>> test_f()
() {}
>>> test_f.count
1
>>> test_f()
() {}
>>> test_f.count
2
This works because wrapped_f
is a local variable inside keep_count
. Since the body of wrapped_f
contains a reference to wrapped_f
, it gets a closure allowing wrapped_f
to access itself.
这篇关于在其自己的内部更改函数的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!