Функция была вызвана 10 раз, но декоратор был вызван только один раз.Зачем? - PullRequest
0 голосов
/ 18 сентября 2018
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)

1 Ответ

0 голосов
/ 19 сентября 2018

Вы прокомментировали:

Я не понимаю, почему декоратор вызывается для функции только один раз.Это надо вызывать 10 раз, верно?Один раз для каждой итерации в цикле и, следовательно, 'Called' должен быть напечатан 10 раз.Чего мне не хватает?

Я думаю, вы путаете запуски декоратора с запусками функции-оболочки (названной в вашем коде helper).Декоратор вызывается только один раз, когда он передается исходной функции и возвращает функцию-обертку, которая хранится как succ в вашем модуле.Обертка - это то, что вызывается вашим циклом десять раз.

Когда я запускаю ваш код, я получаю следующий вывод:

Called

0

0
1
2
3
4
5
6
7
8
9


10

Только первые две строки ("Called" ипустая строка после него) приходит от вызова декоратора.Это можно увидеть, если запустить только определение функции, а не цикл.Вы увидите, что «Called» распечатывается немедленно, даже если вы вообще никогда не вызываете эту функцию.

Ноль вверху и десять внизу взяты из операторов print, которые находятся вверху.уровень.Числа, напечатанные близко друг к другу, являются выводом цикла, который печатает количество предыдущих вызовов непосредственно перед каждым новым вызовом функции с упаковкой.

...