Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorating recursive functions in python

I am having hard time understanding how a decorated recursive function works. For the following snippet:

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))

The output is:

(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

The first one prints f(n) so naturally it prints 'Original' every time f(n) is called recursively.

The second one prints def_f(n), so when n is passed to wrapper it calls f(n) recursively. But the wrapper itself is not recursive so only one 'Decorated' is printed.

The third one puzzles me, which is the same as using decorator @dec. Why does decorated f(n) calls the wrapper five times also? It looks to me that def_f=dec(f) and f=dec(f) are just two keywords bound to two identical function objects. Is there something else going on when the decorated function is given the same name as the undecorated one?

Thanks!

like image 345
jianglai Avatar asked May 25 '12 16:05

jianglai


People also ask

What are the recursive functions in Python?

Python also accepts function recursion, which means a defined function can call itself. Recursion is a common mathematical and programming concept. It means that a function calls itself. This has the benefit of meaning that you can loop through data to reach a result.

Can you decorate a variable in Python?

No, decorator syntax is only valid on functions and classes.

Is Python good for recursion?

In short, recursion is not bad in Python and is often needed for programs that will be doing depth first traversals like web crawlers or directory searches. The Towers of Hanoi smallest steps problem can also be solved using a recursive algorithm with the following Python code.

What are recursive functions examples?

Simple examples of a recursive function include the factorial, where an integer is multiplied by itself while being incrementally lowered. Many other self-referencing functions in a loop could be called recursive functions, for example, where n = n + 1 given an operating range.


1 Answers

As you said, the first one is called as usual.

the second one puts a decorated version of f called dec_f in the global scope. Dec_f is called, so that prints "Decorated!", but inside the f function passed to dec, you call f itself, not dec_f. the name f is looked up and found in the global scope, where it is still defined without the wrapper, so from than on, only f gets called.

in the 3re example, you assign the decorated version to the name f, so when inside the function f, the name f is looked up, it looks in the global scope, finds f, which is now the decorated version.

like image 98
bigblind Avatar answered Sep 24 '22 17:09

bigblind