Question

def tracer(fn):    
    def traced(x):
       print('Calling',fn,'(',x,')')
       result=fn(x)
       print('Got',result,'from',fn,'(',x,')')
       return result
    return traced

def fact(n):   
 if n ==0:
    return 1
 return n * fact(n-1)

new_fact = tracer(fact)  
new_fact(2)

I used this code on pythontutor.com to better understand higher order functions, but i'm having difficulty understanding why new_fact(2) in step 8 is mapped to traced? In other words, how does the traced function know the argument is 2?

Was it helpful?

Solution

In Python, functions are objects too. When you call the tracer() function, it returns the nested traced() function; it is in fact creating a new copy of that function:

return traced

You stored that returned function object in new_fact, then called it:

>>> tracer(fact)
<function traced at 0x10644c320>
>>> new_fact = tracer(fact)
>>> new_fact
<function traced at 0x10644c398>
>>> new_fact(2)
('Calling', <function fact at 0x10644c230>, '(', 2, ')')
('Got', 2, 'from', <function fact at 0x10644c230>, '(', 2, ')')
2

You can do this with any function; store a reference to a function in another name:

>>> def foo(): print 'foo'
... 
>>> bar = foo
>>> bar()
foo
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top