""" As an object, you can assign the function to a variable like any other object. Notice we don't use parentheses: we are not calling the function, we are putting the function "shout" into the variable "scream". """ scream = shout
print scream() # outputs: Yes!
""" More than that, it means you can remove the old name 'shout', and the function will still be accessible from 'scream'. """ del shout try: print shout() except NameError, e: print e # outputs: name 'shout' is not defined
defmy_shiny_new_decorator(a_function_to_decorate): """ Inside, the decorator defines a function on the fly: the wrapper. This function is going to be wrapped around the original function so it can execute code before and after it. """
defthe_wrapper_around_the_original_function(): """ Put here the code you want to be executed BEFORE the original function is called """ print"Before the function runs"
# Call the function here (using parentheses) a_function_to_decorate()
""" Put here the code you want to be executed AFTER the original function is called """ print"After the function runs"
""" At this point, "a_function_to_decorate" HAS NEVER BEEN EXECUTED. We return the wrapper function we have just created. The wrapper contains the function and the code to execute before and after. It’s ready to use! """ return the_wrapper_around_the_original_function
# Now imagine you create a function you don't want to ever touch again. defa_stand_alone_function(): print"I am a stand alone function, don't you dare modify me"
a_stand_alone_function() # outputs: I am a stand alone function, don't you dare modify me
""" Well, you can decorate it to extend its behavior. Just pass it to the decorator, it will wrap it dynamically in any code you want and return you a new function ready to be used: """
a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function) a_stand_alone_function_decorated() """outputs: Before the function runs I am a stand alone function, don't you dare modify me After the function runs """
defa_decorator_passing_arbitrary_arguments(function_to_decorate): # The wrapper accepts any arguments defa_wrapper_accepting_arbitrary_arguments(*args, **kwargs): print"Do I have args?:" print args print kwargs # Then you unpack the arguments, here *args, **kwargs # If you are not familiar with unpacking, check: # http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ function_to_decorate(*args, **kwargs)