Python Decorators as Closures
Python decorators are a feature of the language that allows the programmer to alter the behavior of a function or class at runtime and without having to use techniques such as subclassing.
For example, let’s assume I need to trace the code path over several functions. This is easily accomplished with a decorator:
def myTrace(f): def trace_func(): print "Entered", f.__name__ f() print "Exiting", f.__name__ return trace_func @myTrace def function1(): print "Inside Function1" function2() @myTrace def function2(): print "Inside Function2" function1()
The output of this script is:
Entered function1 Inside Function1 Entered function2 Inside Function2 Exiting function2 Exiting function1
Decorators in Python allow me to do more than just simple text substitution (C
macros). Decorators effectively replaced one function for another in the example
above. I can prove that there is actual substitution by adding the statement
print function1.__name__
to the end of the above script. What is
the current name of function1?
The more interesting thing that decorators allow me to do is to close over the parent scope of the decorator. Let’s look a this example:
def helloWorld(f): s = "World!" def new_func(): print f(), s return new_func @helloWorld def func(): return "Hello" func()
The output of the script above is Hello World!, but the only call is to
func()
and that function does not print anything. This is because I substitute
func()
for the new_func()
definition that I created inside the
decorator. The new definition is, for all intents and purposes, a closure,
because it encapsulates the context of the decorator and of func()
.
I can prove this theory: comment out the @helloWorld
decorator before the
func()
definition and run the script again. What is the output now?
Comments
Comments powered by Disqus