Мне трудно понять, как работает оформленная рекурсивная функция. Для следующего фрагмента:
def dec(f):
def wrapper(*argv):
print(argv, 'Decorated!')
return(f(*argv))
return(wrapper)
def f(n):
print(n, 'Original!')
if n == 1: return(1)
else: return(f(n - 1) + n)
print(f(5))
print
dec_f = dec(f)
print(dec_f(5))
print
f = dec(f)
print(f(5))
Вывод:
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
((4,), 'Decorated!')
(4, 'Original!')
((3,), 'Decorated!')
(3, 'Original!')
((2,), 'Decorated!')
(2, 'Original!')
((1,), 'Decorated!')
(1, 'Original!')
15
Первый печатает f(n), поэтому, естественно, он печатает 'Original' каждый раз, когда f(n) вызывается рекурсивно.
Второй печатает def_f(n), поэтому, когда n передается обёртке, он рекурсивно вызывает f(n). Но сама оболочка не является рекурсивной, поэтому печатается только один «Decorated».
Третий вопрос меня озадачивает, это то же самое, что использовать декоратор @dec. Почему декорированный f(n) также вызывает обертку пять раз? Мне кажется, что def_f=dec(f) и f=dec(f) — это всего лишь два ключевых слова, привязанных к двум идентичным функциональным объектам. Происходит ли что-то еще, когда декорированной функции дается то же имя, что и недекорированной?
Спасибо!