Декоратор - изменение имени переменной
Я изучаю концепции декораторов в 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.
только чтобы показать, что эта переменная внутри helper
функция), но только определил helper.calls
после использования здесь, к концу.
Аналогично, ближе к концу, после вызова функции декоратора, автор неожиданно использовал succ.calls
переменная - которая даже печатает ожидаемый результат - но без какого-либо определения.
PS Я пытался сделать свое исследование, но не мог даже описать это поведение правильными словами, чтобы найти что-нибудь подходящее.
PPS Не смог придумать более точный заголовок, так как совершенно незнаком с фактическим происходящим явлением.
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