Python 在函数自身的主体内更改函数的属性?
我正在尝试创建一个函数,该函数记录调用它的次数,我希望信息留在函数本身中。 我尝试创建一个包装器,如下所示:Python 在函数自身的主体内更改函数的属性?,python,function,python-3.x,decorator,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,
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)
我原以为它会起作用,但我得到一个属性错误
说“function”对象没有属性“count”
我已经解决了这个问题:这是因为装饰器将我的test\u f
设置为等于wrapped\u f
(在keep\u count
装饰器中定义),并且我正在增加原始f
的计数,因为test\u f
引用了新函数,所以不再使用它
有没有一种方法可以在不进行太多黑客攻击的情况下做到这一点?只需将属性设置为
wrapped\u f
而不是f
。这要求您在定义函数后设置初始计数
,但这没什么大不了的:
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\u f
是keep\u count
中的局部变量。由于wrapped\u f
的主体包含对wrapped\u f
的引用,因此它得到一个闭包,允许wrapped\u f
访问自身。为什么不使用类?这就是类的用途——创建有状态上下文来运行函数in@AdamSmith既然python函数是对象,它们不能同时维护状态吗?@wegry当然可以。你也可以用一把钳子把两块板钉在一起:)事实上,这段代码在Python 3.4上运行得很好。@MarkusMeskanen这里没有AttributeError。哇,我一直认为你不能在其内部使用函数。。。再说一次,从我记事起我就一直在使用递归函数,我不明白为什么我不能这样做。O只是有一种误解。好吧,谢谢你的回答,我想你每天都能从旧东西中学到新东西!:)@马库斯梅斯卡宁:你可以,或多或少,但你必须小心,因为名字查找发生在不同的时间。啊,是的,谢谢…:)我会继续深入研究,我会尽快接受。