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