Directory of this chapter:
Adorner:
First, why use the adorner
Second, what is the adorner
Three, non-parametric decorative device
Four, the decorator grammar sugar
Five, the certification adorner implementation
VI. Overlay multiple adorners
Seven, with the decorative device
===========================================================
I. Open and closed principle
Primer--Why use an adorner
Once the software is online, it is closed to the modification of the source code and is open to the function extension.
That means we have to find a solution:
Ability to add new functionality without modifying a feature source code and calling mode
Summary, the principles are as follows:
1, do not modify the source code
2. Do not modify the calling method
Objective:
Extend new functionality on the basis of principle 1&2
Second, what is the adorner
An adorner (Decorator) is a special function used to add new functions to a function.
It is primarily used to extract similar code that is not related to the function itself in a large number of functions and continue to reuse.
The adorner can also be divided into parameters and without parameters.
Full meaning:
The adorner adds new functionality to the adorner object without modifying the source code and calling method of the object being decorated.
The adorner and the decorated object can be any callable object
Decorators >>> functions
Objects >>> functions being decorated
Third, the decoration of the implementation of the non-parametric adorner
The implementation of the adorner cannot be detached, the source code cannot be modified, and the principle of the source invocation mode cannot be modified. Below we will follow the implementation of the idea of the adorner, step by step implementation of the adorner.
Increase the run timing function for the following program.
Import Time def index (): time.sleep () print('This isindex page! ')
Scenario 1:
Import Time 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 ()
# Although the scheme achieves the timing function, it modifies the source code and violates the two principles of the adorner.
Scenario 2:
Import time # introduces a timing packet to make it easy to call The Times () method def index (): Time.sleep (2 ) print('This isIndex Page. ' == time.time ()print('The running time is%s' % (stop_time-start_time)
# Although the program has achieved the timing function, but only for the addition of code, if the other program to time, but also to rewrite once, can not be reused.
Scenario 3:
Import Time def index (): time.sleep (2) print('This isindex Page' )def== time.time () print(' The running time is %s'
# Although the scheme achieves the timing function, it also calls wrapper () to display the timing, changing the way the original function is called
Scenario 4:
Import Timedefindex (): Time.sleep (2) Print('The IS Index Page')defWrapper (func):#func = Indexstart_time=time.time () func (); #IndexStop_time =time.time ()Print('The running time is %s'%(Stop_time, start_time)) wrapper (index)
# Although the scheme achieves the timing function, it is necessary not only to call wrapper (), but also to import the original function index as a parameter and change the method of calling the original function .
Scenario 5 (No parametric decorator on the right track):
Import Timedefindex (): Time.sleep ()Print('The IS Index Page')defOutter (func):# func = Most initial index #func = Index skillfully uses closures, passing parameters, #The parameters of the outer function band are prepared for use in internal functions, and this is the closure function . defwrapper (): Start_time=time.time () func () Stop_time=time.time ()Print('The running time is %s') returnWrapperindex= Outter (Index)#the initial index function has been processed and changed to Outter (index), which is "decorated"index ()
# This method can show the running time, is the most initial index function through the characteristics of the closure, after processing and re-the new function memory address, assigned to index, the index function is not the original index, it has been "decorated"
Scenario 6 (Upgraded version of Scenario 5):
1. No parameter adorner, an error occurred while introducing the parameter function.
#unlike the index () function, this time we introduce a new function with the parameter call_you (name)Import Timedefcall_you (name): Time.sleep (2) Print('I Call you%s'%name)defOutter (func):defwrapper (name): Start_time=time.time () Res=func (name) stop_time=time.time ()Print('The running time is %s'% (Stop_time-start_time)returnResreturnWrapperindex=outter (Index) Home= Outter (Home)#home with the parameter, but the index does not take the parameter, here the operation will error
Scenario 7 (Problem with solution 6):
# using variable length parameters to deal with this problem
# variable length parametric template, note that the parameter is *args **kwargsdef Outter (func) :def inner (*args, * * Kwargs): = func (*args, * * Kwargs )return resreturn Inner
Import Timedefcall_you (name): Time.sleep (2) Print('I Call you%s'%name)defOutter (func):defWrapper (*args, * *Kwargs): Start_time=time.time () Res= Func (*args, * *Kwargs) Stop_time=time.time ()Print('The running time is %s'% (Stop_time-start_time)) returnResreturnWrapper
Call_you=outter (call_you) call_you ('Puppy')
Four, the decorator grammar sugar
Grammatical sugars are those that do not add new functionality to a computer, but are a more "sweet" syntax for humans, which increases the readability of the program and reduces the chance of code errors.
# note the placement of the grammar sugar, put it at the top of the function you want to use, and start with @
Five, the certification adorner implementation
1. Simple implementation of the authentication module:
2. Login for verification After adding the authentication module:
VI. Overlay multiple adorners
# Note The order of multiple adorners, executed in sequence
1. Certified Decorators
2. Timing Decorator
3. Overlay multiple adorners (note the order of precedence)
Seven, with the decorative devicewith parameters, which gives the adorner greater flexibility. The only parameter of the non-parametric adorner written above is the execution of the corresponding business function. The adorner syntax allows us to provide additional parameters when calling. New parameters provide greater flexibility in the authoring and use of adorners。The use_logging above is an adorner that allows parameters. It is actually a function encapsulation of the original adorner and returns an adorner. We can interpret it as a closed packet with parameters. when we call, Python can discover this layer of encapsulation and pass parameters to the adorner's environment.
The adorner for the function of getting started with Python