@decorator can dynamically realize the increase of function function, however, after @decorator "transformation" function, compared with the original function, there is no other place than the function of a little more?
In the absence of decorator, print the function name:
def F1 (x): Pass Print F1. __name__
Output:
F1
In the case of decorator, the function name is printed again:
def log (f): def Wrapper (*args, * *kw) :print'call... ' return F (*args, * *kw )return wrapper@logdef F2 (x) : passprint F2. __name__
Output:
Wrapper
As you can see, the new function functions returned by decorator are not ' F2 ', but are @log internally defined ' wrapper '. This will invalidate the code that relies on the name of the function. Decorator also changes other properties such as __doc__ of the function. If you want the caller to see that a function has undergone a @decorator transformation, you need to copy some of the properties of the original function into the new function:
def log (f): def Wrapper (*args, * *kw) :print'call... ' return F (*args, * *kw) wrapper. __name__ = f.__name__ wrapper. __doc__ = f.__doc__ return Wrapper
It is inconvenient to write decorator because it is difficult to copy all the necessary properties of the original function to the new function, so Python's built-in Functools can be used to automate this "copy" task:
Import Functools def log (f): @functools. Wraps (f) def Wrapper (*args, * *kw) :print 'call... ' return F (*args, * *kw )return Wrapper
Finally, it is necessary to point out that since we have changed the original function signature (*args, **kw), we cannot get the original parameter information of the original function. Even if we use fixed parameters to decorate a function with only one parameter:
def log (f): @functools. Wraps (f) def Wrapper (x): print' Call ... ' return f (x) return Wrapper
It is also possible to change the parameter name of the original function because the parameter name of the new function is always ' x ', and the parameter name defined by the original function is not necessarily called ' X '.
Perfect decorator in Python