Мне сложно понять, как работает декорированная рекурсивная функция. Для следующего фрагмента кода:Оформление рекурсивных функций в python
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
Первый принты е (п), поэтому, естественно, он печатает «оригинал» каждый раз, когда п (п) называется рекурсивно.
Второй печатает def_f (n), поэтому, когда n передается в оболочку, он вызывает f (n) рекурсивно. Но сама оболочка не рекурсивна, поэтому печатается только один «Украшенный».
Третий меня озадачивает, что аналогично использованию декоратора @dec. Почему украшенный f (n) также вызывает обертку пять раз? Мне кажется, что def_f = dec (f) и f = dec (f) - это всего лишь два ключевых слова, привязанных к двум идентичным объектам функции. Есть ли что-то еще, когда украшенной функции присваивается то же имя, что и декорированный?
Спасибо!
ссылка на оригинальный 'f' функции по-прежнему существует, таким образом, что одна называется. Когда вы выполняете 'f = dec (f)', вы всегда будете вызывать новую функцию. И новая функция вызовет оригинал. – JBernardo
'decorator' может не быть подходящим термином для использования здесь, так как вы никогда не применяете декоратор к функции. Ваш последний тест 'f = dec (f)' почти (если не точно) совпадает с '@dec def f' –