Декорирование рекурсивных функций в python
==========================================

Мне трудно понять, как работает декорированная рекурсивная функция.
Для следующего фрагмента:

Выход:

Первый из них печатает f (n), поэтому, естественно, он печатает «Оригинал». каждый раз, когда f (n) вызывается рекурсивно.

Второй выводит def\_f (n), поэтому, когда n передается в оболочку, он вызывает f (n) рекурсивно. Но сама обертка не является рекурсивной, так что только один «Декорированный» печатается.

Третий меня озадачивает, это то же самое, что и использование декоратора @dec. Почему оформленный f (n) также вызывает обертку пять раз? Мне кажется, что def\_f = dec (f) и f = dec (f) - это просто два ключевых слова, связанных с двумя одинаковыми функциональными объектами. Есть ли что-то еще, когда декорированная функция имеет то же имя, что и неокрашенная?

Спасибо!

второй помещает декорированную версию f с именем dec\_f в глобальную область видимости. Вызывается dec\_f, чтобы печатать "Decorated!", Но внутри функции f, переданной в dec, вы вызываете сам f, а не dec\_f. имя f ищется и находится в глобальной области видимости, где оно все еще определено без оболочки, поэтому с этого момента вызывается только f.

в примере 3re вы назначаете декорированную версию имени f, поэтому, когда внутри функции f ищется имя f, она ищет в глобальной области видимости f, которая теперь является декорированной версией.



`f`, какой питон смотрит в области видимости.

До утверждения`f = dec(f)`, `f` все еще связан с развернутой функцией, так что вызывается.



one до или после другой функции, мы можем избежать этогоseveral times имитирующие декораторы с рекурсивными функциями.

Например:

Производит:

Мы можем смоделировать декоратор, чтобы заставить только один пролог / эпилог как:

Который производит:



Я думаю, что это могло бы сделать вещи немного более понятными, функция-обертка фактически закрывает объект func от ограничивающей области. Таким образом, каждый вызов func внутри оболочки будет вызывать оригинальный f, а рекурсивный вызов внутри f будет вызывать декорированную версию f.

Вы можете увидеть это, просто распечатав`func.__name__` внутри обертки и`f.__name__` внутри функции`f`



 тебя есть

то, что вы делаете, привязывает имя`f` к возвращаемому значению`dec(f)`, В таком случае,`f` больше не относится к исходной функции. Исходная функция все еще существует и вызывается новой`f`, но у вас нетnamed ссылка на оригинальную функцию больше.