It is often seen in python that defining a function is using @func. This is the adorner, which is a function that takes a function as a parameter, and is often used to extend an existing function without changing the current function state.
def run (): print "I ' m run."
I have such a function that I want to know when the function begins to end. I should have written that.
def run (): print time.ctime () print "I ' m run." Print Time.ctime ()
But if you don't allow the function to be modified, you need an adorner.
def count (func): def wrapper (): print time.ctime () ret = func () print time.ctime () return ret return Wrapper@countdef Run (): print "I ' m run." # print ' 2015-4-10 '
eg
def now (): print ' 2015-4-10 ' F = NOWF ()
The function has a __name__ object that can be defined by the Dir (func) Func function name
now.__name__ # print ' Now ' f.__name__ # print ' Now ' Print F # print '
print now # print '
'
We print log logs via adorners
def log (func): def wrapper (*args, **kwargs): print "Call%s ()"% func.__name__ return func (*args, * * Kwargs) return wrapper@logdef Now (): print ' 2015-4-10 ' Today () # print ' Call Now () '
In fact, the decorator modifier function is equivalent to now = log (now), which is the adorner function assigns the modified function to a variable of the same name after the argument
Functools.wraps function
When we used the adorner, now the __name__ value has changed.
# not used before now.__name__ # print ' Now ' # after using now.__name__ # print ' wrapper '
When we use the adorner, NOW.__NAME__ uses the current now function, but after the use of this function is actually the log (now) and the return value of the log function is the wrapper of the parcel. The workaround is the Functools.wraps function.
decorate closures, call import Functools before use
def log (func): @functools. Wraps (func) def wrapper (*args, **kwargs): ...
Adorner with parameters
If decorator needs to pass in parameters, it is necessary to write a higher-order function that returns decorator. It's more complicated to write.
def login: def _deco (func): def wrapper (*args, **kwargs): If level >= 5: print ' user VIP rank%d '% Int (level-5) else: print ' user cock wire level%d '% abs (level-5) return func (*args, **kwargs) return wrapper< C13/>return _deco@login (5) def user (username): print ' welcome,%s '% username# user VIP level 0# Welcome, Minkuser (' mink ')
Decorator with parameters equals Func = Adorner function (adorner parameter) (func)
Adorner class
You can use a class like a function by __call__ the class
Class A (object): def __init__ (Self, func): Self.func = func def __call__ (self): return Self.func () * * 2 @Adef foo (): return 10print foo () # Print 100