我正在学习Python中装饰器的概念。虽然我认为我已经覆盖了许多博客,并且对装饰器的工作原理以及为什么需要装饰器有了一些基本的了解。
这样做的时候,我遇到了一个教程(完全失去了对此的参考),其中在解释装饰器时,作者写道:
def call_counter(func):
def helper(x):
helper.calls += 1
return func(x)
helper.calls = 0
return helper
def succ(x):
return x + 1
succ = call_counter(succ)
print(succ.calls)
for i in range(10):
succ(i)
print(succ.calls)
输出:
0
10
正如我之前提到的,我以为我了解装饰器的工作原理和基本的Python,但突然在这里怀疑自己。
在辅助函数中,作者将helper.calls
变量加1(根据我以前的理解,该变量应该只是一个普通变量,而helper.
只是表明该变量位于{{ 1}}函数),但直到最后才在这里使用helper
。
类似地,最后,在调用装饰器函数之后,作者突然使用了helper.calls
变量-甚至可以打印预期的结果-但没有任何定义。
P.S。我曾尝试进行研究,但甚至无法用适当的措辞来找出这种行为。
P.P.S。无法提供更精确的标题,因为它完全不了解实际发生的现象。
答案 0 :(得分:1)
succ = call_counter(succ) # succ.calls = 0 when function is called (succ = helper)
print(succ.calls) # prints 0
for i in range(10):
succ(i) # As succ = helper now, this becomes helper(i) and helper.i is incremented by 1 each iteration, succ(x) is then returned after as func = succ and x + 1 is returned from succ(x)
print(succ.calls) # prints 10 as helper.calls is incremented 10 times within the loop
如果succ(x)不返回任何值,因为没有在其他地方使用它,则将获得相同的输出,您可以在http://www.pythontutor.com/visualize.html#mode=edit上看到可视化的代码