def call_counter(func):
print('Called\n')
def helper(x):
helper.calls+=1
return func(x)
helper.calls=0
return helper
@call_counter
def succ(x):
return x+1
print(str(succ.calls)+'\n')
for i in range(10):
print(succ.calls)
succ(i)
print('\n')
print(succ.calls)
你评论说:
我不明白为什么只在函数上调用一次装饰器。它应该被称为10次,对吗?循环中每次迭代一次,因此“被调用”应打印10次。我错过了什么?
我认为你是装配器运行包装器函数(在你的代码中名为helper
)的混乱。装饰器只被调用一次,当它被传递给原始函数并返回包装函数时,它将被存储为模块中的succ
。包装器是循环调用十次的包装器。
当我运行你的代码时,这是我得到的输出:
Called
0
0
1
2
3
4
5
6
7
8
9
10
只有前两行(“Called”和它后面的空行)来自装饰器调用。如果只运行函数定义而不是循环,则可以看到这一点。即使您根本不打电话,也会立即打印出“被叫”。
顶部的零和底部的十个来自顶级的print
语句。靠近打印的数字是循环的输出,它在对包装函数进行每次新调用之前打印先前调用的计数。