First, the decoration device
Decorator is a kind of application scenario of closure function
What is a closure function? Let's take a moment to recall:
Closure function:
A function defined inside a function that contains a reference to the outer function scope (emphasizing: a reference to a global action domain name is not a closed packet) name, which is called a closure function
Speaking of scopes, we'll recall:
Scope:
Global scope: Built-in + global
Globally valid, global survival
Local Range: Local
Locally valid, local survival
Scope relationships are defined in the function definition phase, regardless of the location of the call,
That is, no matter where the function is called, you must go back to where you defined the function to find the scope relationship
First, why use the adorner
#开放封闭原则: #软件一旦上线后, we should follow the principle of open closure, to modify the source code is closed, the expansion of the function is open, that is, we must find a solution: #能够在不修改一个功能源代码以及调用方式的前提下, add new features.
Second, what is the adorner
#装饰器他人的器具, itself can be any callable object, the adorner can be any callable object. #强调装饰器的原则: #1, do not modify the source code of the adorned object #2, do not modify the calling way of the decorated object # adorner target: #在遵循1和2的前提下, add new features to the adorned object
Third, the use of decorative device
#我们现在给下面函数增加一个运行时间的功能import Timedef Index (): time.sleep (3) print (' Welcome to Index page ') #修改一def index (): start_time=time.time () time.sleep (3) print (' Welcome to Index page ') stop_time=time.time () Print (' Run time is%s '% (stop_time-start_time)) index () #功能实现 # Comments: Directly change the source code, so it was opened ...
#再来一位童靴, to implement the function # Modify two import Timedef index (): time.sleep (1) print (' Welcome to Index page ') start_time=time.time () index () Stop_time = Time.time () print (' Run time is%s '% (stop_time-start_time)) #评语: There are many functions to implement this function, write n times the code, #后期维护一脸懵逼, Or is it open ...?
#再来一位童靴, functional repeat implementation look at me with a powerful function # revision three: Import Timedef index (): time.sleep (3) print (' Welcome to Index page ') def wrapper ( Func): #func =index start_time=time.time () func () #index () stop_time = Time.time () print (' Run Time is%s '% (stop_time-start_time)) wrapper (index) #评语: Modified the way the original function was called, still open ...
#终于来了位小牛的童靴, the value of the function can be returned, and then I'll redefine index# revision four: Import Timedef index (): time.sleep (3) print (' Welcome to index page ') def outter (func): #func = Most original index # func= Most original index def wrapper (): start_time=time.time () Func () stop_time=time.time () print (stop_time-start_time) return Wrapperindex=outter (index) # new Index=wrapperindex () #wrapper () function Basic Implementation # Reviews: There is no problem when the original value does not return a value, but with the return value, this will find that none is returned.
#这次小牛牛童靴路过看到这情况, say! #修订五import Timedef Index (): time.sleep (1) print (' Welcome to Index page ') return 123 #假使这里返回123 The return value can be any type #============== below is the adorner def Timmer (func): #func = The most original index def wrapper (*args,**kwargs): # Variable length parameter start_time=time.time () res=func (*args,**kwargs) #调用最原始的index stop_time=time.time () return value for print (stop_time-start_time) return res #index () returns Wrapperindex=timmer (index) # New Index=wrapperprint (Index ()) #功能已经实现, return value 123# reviews: The function of the decoration here has been realized, the returned value is also obtained, the calf ox is not white-called
#天上五彩红光, the boy boots appeared! Ladies and gentlemen, the boots are in the crowd.!import timedef Timmer (func): def wrapper (*args,**kwargs): start_time=time.time () Res=func (*args,**kwargs) stop_time=time.time () print (stop_time-start_time) return res Return Wrapper@timmer #index The standard format of the =timmer (index) Adorner! def index (): time.sleep (1) print (' Welcome to Index page ') return 123@timmer # Home=timmer (home) def home ( Name): time.sleep (2) print (' Welcome%s to home page '%name) # index () #home (' Egon ') #评语: Daniel is Daniel! Daniel say: Teach you stunt, not the child boots can be implemented according to the following template: #无参装饰器模板def outer (func): #outer, inner name function free def inner (*args,**kwargs): Res=func (*args,**kwargs) return res return inner@outer #装饰器要在装饰函数的上方def Duoduo (): Pass
Four, decorator syntax
#被装饰函数的正上方, a single line @deco1@deco2@deco3def foo (): pass#foo=deco1 (Deco2 (Deco3 (foo))) #这里的思想就是最上面装饰器, decorating all of the following functions ( Deco2,deco3,foo) #然后deco2装饰 (Deco3,foo), the final Deco3 decoration foo# function of the different, put the order should also pay attention to, otherwise the effect of decoration may be wrong!
Use of five or more adorners:
Import timecurrent_user={' username ': None, # ' login_time ': None}def auth (func): # Func=index def wrapper (*args, **kwargs): If current_user[' username ': #这里是认证过的, next time you do not have to certify print (' already logged in ') Res=func (*args,**k Wargs) return res uname=input (' User name >>: '). Strip () pwd=input (' Password >>: '). Strip () I F uname = = ' Egon ' and pwd = = ' 123 ': print (' login successful ') current_user[' username ']=uname res=func (*args,**kwargs) return res else:print (' User name or password error ') return Wrapperdef Timmer (func): def Wrapper (*args,**kwargs): Start_time=time.time () Res=func (*args,**kwargs) stop_time=time.time () Print (Stop_time-start_time) return res return Wrapper@timmer # Timmer statistics are Auth+index execution time @auth #我们 If you decorate index only, keep @timmer immediately. IndexDef index (): Time.sleep (1) Print (' Welcome to Index page ') return 123@auth@timmer # This is the time for home run Def Home(name): Time.sleep (2) print (' Welcome%s to home page '%name) #index () #home ("Duoduo")
Six, the use of parameters of the adorner:
Import timecurrent_user={' username ': None, # ' login_time ': none}def auth (engine): #道理还是那个道理, the value of an engine on the outer bread # E ngine= ' file ' #这个值外面穿什么进来就是什么 def auth2 (func): # Func=index def wrapper (*args,**kwargs): If en Gine = = ' file ': If current_user[' username ': print (' already logged in ') Res=func (*args,**kwargs) return res uname=input (' User name >>: '). Strip () Pwd=inpu T (' Password >>: '). Strip () if uname = = ' Egon ' and pwd = = ' 123 ': print (' login successful ') current_user[' username ']=uname res=func (*args,**kwargs) return res Else:print (' Username or password error ') elif engine = = ' MySQL ': #engine worthy of judgment Print (' MYQL-based authentication ') elif engine = = ' LDAP ': Print (' LDAP-based authentication ') return wrapper return AUT H2 #这里也要返回auth2的内存地址@auth (' LDAP ') # @auth2 #index =auth2 (index) #index =wrapperdef index (): Time.sleep (1) Print (' Welcome to index page ') Return 123index () # Wrapper ()
Application of Python development decorator