Декоратор - изменение имени переменной

Я изучаю концепции декораторов в 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

Другие вопросы по тегам