Learning adorners prerequisites need to know higher order functions, function nesting, function closures
The Python function decorator, as its name implies, is a way of decorating functions that add new functionality to a function.
Why use adorners?
Because functions are added at run time without the use of adorners, the function source code needs to be modified, which undoubtedly increases the redundancy and complexity of the program and makes it easier for programmers to modify it. Using the adorner, you can add the function function by using the syntax sugar @ adorner without changing the source code and calling mode of the function.
An adorner is essentially a function.
We use a simple example to achieve:
Import Time#This is an adorner function named TimerdefTimer (func):#passing the original function (func) to the adorner function as a parameter defWapper ():#defining the Adornment function WapperStart_time=time.time () func ()#call the original functionStop_time=time.time ()Print("program run time is%s"% (stop_time-start_time)) returnWapper#returns the Wapper function to the timer@timer#define Index=timer (index)defindex (): Time.sleep (2) Print("This is a test program") index ()
The above is a parameterless adorner, sometimes we need to use the parameters of the adorner, such as login verification,
Import Time#This is an adorner function named Timerdeftimer1 (auth_type):Print(Auth_type)#print Auth_type values for easy viewing of your program flow defTimer (func):#passing the original function (func) to the adorner function as a parameter defWapper ():#defining the Adornment function Wapper ifauth_type=="file": Start_time=time.time () func ()#call the original functionStop_time=time.time ()Print("program run time is%s"% (stop_time-start_time)) Else: Print("I don't know what you're typing.") returnWapper#returns the Wapper function to the timer returnTimer#return timer to timer1@timer1 (Auth_type="file")#define Index=timer (Index (AUTH_TYPE))defindex (): Time.sleep (2) Print("This is a test program") index ()
In the process of using adorners we found that the source information of the original function is missing, when we need the original function return value, in the original function can not be returned or not, which requires us to re-understand the role of the adorner syntax sugar, it is not difficult to find that the original function has become a function in the adorner wapper
The following example tests according to the code above:
By using, we find that the meta-information of the original function shows the result is None
@timer1 auth_type= " file ") # define Index=timer ( Index (AUTH_TYPE)) def index (): Span style= "COLOR: #800000" "" "" This is the original function information Time.sleep ( 2 print (" This is a test program " ) print ( Index. __doc__ ) # result is none
After experimentation, it is possible to verify that the meta information of the modified function is added in the adorner to print effectively
def Wapper ():# define adornment function Wapper"" "" " in the adorner " ""
In this case, we can use the Functools.wraps wraps itself is also an adorner, he can copy the meta-information of the original function into the adorner, so that the adorner function has the same source information as the original function
from Import Wraps# Call tool def timer1 (auth_type): print(auth_ Type)# print Auth_type value, easy to see the program process def timer (func):# The original function (func) is passed in as a parameter to the adorner function @wraps (func) Inserts the tool adorner into the adorner function just above the def Wapper ():# defining the adornment function Wapper
We can also define multiple adorners to use for the function, and notice the order in which the adorner is called
@a
@b
@c
def f ()
This decoration is equivalent to f=a (b (C (f)))
Python function Adorner