One: decorator
On the basis of not changing the original function, additional functions are added.
The return value of the decorator is a function object.
Decorator application: logging, performance testing, transaction processing, caching and other scenarios.
Two: the formation process of the decorator
Application of a function: calculating execution time
import time def func1(): print('in func1') def timer(func): def inner(): start_time=time.time() func() end_time=time.time() print(end_time-start_time) return inner func1 = timer (func1) func1()
It is too troublesome to use func1=timer(func1) when applying multiple functions, so there is syntactic sugar.
No parameter decorator (simple decorator)
import time def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner @timer # ==> func1 = timer (func1) def func1(): print('in func1') func1()
Universal decorator (function with parameters)
def wrapper(func): def inner(*args,**kwargs): ret = func (* args , ** kwargs ) return ret return inner # @wrapper # def func(): # print() # func()
Interpretation: The omitted part is used when we want to call this decorator to execute the function.
Decorator with parameters (see function name and declaration information)
def wrapper(func): def inner(*args,**kwargs): ret = func (* args , ** kwargs ) return ret return inner @wrapper def func(): print() func()
from functools import wraps def deco(func): @wraps(func) #Add just above the innermost function def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''Ha ha ha ha''' print('from index') print(index.__doc__)
with flag decorator
def outer(flag): print('Don't go to work') def wrapper(func): print('It's been a week') def inner(*args,**kwargs): if flag: print('Decorators are a headache') ret=func(*args,**kwargs) if flag: print('I'm going, it's not over yet') return ret return inner return wrapper @outer(True) def func(): print('Finally on vacation') func()
bug: @outer ( True ) must put 500
Improve
flag = True def wrapper_out(flag): def wrapper(func): def inner(*args,**kwargs): '''Before executing the function''' if flag: ret = func (* args , ** kwargs ) '''After executing the function''' print(222) return ret else : ret = func () return ret return inner return wrapper @wrapper_out(flag) #The first step is to call wrapper_out(flag) and receive the return value wrapper def func(): #The second step is @wrapper, that is, func = wrapper(func) print(111) func()
Multiple decorators decorate a function
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()