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