python调用序列中的decorator

python调用序列中的decorator,python,python-3.x,Python,Python 3.x,我正在尝试用Python3编写一个decorator,它基本上会记录函数被调用的次数。 这是我的密码: def call_counter(func): def helper(x): helper.calls += 1 return func(x) helper.calls = 0 return helper @call_counter def succ(x): return x + 1 for i in range(10): print(su

我正在尝试用Python3编写一个decorator,它基本上会记录函数被调用的次数。 这是我的密码:

def call_counter(func):
  def helper(x):
      helper.calls += 1
      return func(x)

  helper.calls = 0

  return helper


@call_counter
def succ(x):
  return x + 1

for i in range(10):
  print(succ(i))   # <--- ??
我理解decorator是如何工作的,但这里唯一让我感到困惑的是,有史以来第一次调用sucx得到了一个函数作为返回@call\u counter decorator。 然而,这里的主要困惑是我不太理解for循环中的顺序调用是如何在这里发生的

那么,在我们从第一次调用返回函数helper之后,流是如何进行的呢


现在在for循环中,调用了suc0、suc1等,这是如何工作的?我们是重用从第一次调用中得到的返回函数,还是每次for循环被1添加时都会调用decorator

装饰器只在满足它时应用一次,之后所有的成功调用都使用您返回的同一个函数

如果只是在for循环中打印函数对象而不是调用它,则可以看到这一点:

for i in range(10):
  print(succ)
<function call_counter.<locals>.helper at 0x7fe4d05139d8>
<function call_counter.<locals>.helper at 0x7fe4d05139d8>
# ... so on, ten times.

流程是直接向前的,每次都会使用传递给func的参数x调用helper。

值得一提的是,如果您想使装饰器透明,可以使用functools.wrapps。谢谢Jim,但我认为您的意思是将printsucc放在succ中,而不是放在for循环中,对吗?但我明白你的意思。