decorators decorator is function whose primary purpose is to wrap another function or class the primary purpose of this wrapping is to transparently alter or enhance the behavior of the object being wrapped syntacticallydecorators are denoted using the special symbol as follows@trace def square( )return * the preceding code is shorthand for the followingdef square( )return * square trace(squarein the examplea function square(is defined howeverimmediately after its definitionthe function object itself is passed to the function trace()which returns an object that replaces the original square nowlet' consider an implementation of trace that will clarify how this might be usefulenable_tracing true if enable_tracingdebug_log open("debug log"," "def trace(func)if enable_tracingdef callf(*args,**kwargs)debug_log write("calling % % % \ (func _name_ _argskwargs) func(*args,**kwargsdebug_log write("% returned % \ (func _namer)return return callf elsereturn func in this codetrace(creates wrapper function that writes some debugging output and then calls the original function object thusif you call square()you will see the output of the write(methods in the wrapper the function callf that is returned from trace(is closure that serves as replacement for the original function final interesting aspect of the implementation is that the tracing feature itself is only enabled through the use of global variable enable_tracing as shown if set to falsethe trace(decorator simply returns the original function unmodified thuswhen tracing is disabledthere is no added performance penalty associated with using the decorator when decorators are usedthey must appear on their own line immediately prior to function or class definition more than one decorator can also be applied here' an example@foo @bar @spam def grok( )pass lib fl ff