Before learning the decorator function, consider the following two scenarios:
a.
**There is a function fn, we can not modify the source code of the function, but how to realize the function of the function? **
We can define a new function deco, and then perform an assignment operation like fn=deco(fn), then when the original fn is called, the deco(fn) operation is actually performed. If this method works , We face the following problems:
The deco function must accept a function as a parameter, and the deco function must also return a function. Obviously, the accepted function must be a function fn, and the returned function needs to have both the function of fn and the extended function. Therefore, the structure of the deco function can be as follows:
def deco(fn):
def wrapper(*args,**kwargs): #The purpose of the parameters here is to pass to the fn function.
CODE ... #New function code if any
fn(*args,**kwargs)
CODE ... #New function code if any
return wrapper
# The calling method is as follows:
fn=deco(fn)fn(*args,**kwargs) #Does not change the way the fn function is called
b.
**There is a function wrapper, how do we pass additional parameters to the function wrapper without changing the way the function is called? **
We can change the wrapper by means of assignment, such as wrapper=func(args), where args is the extra parameter we want to pass, and func is a new function. The func function needs:
Accept the additional parameter args we want to pass, and need to return a function at the same time. The returned function should be the wrapper function. As for how the passed parameter args is given to the wrapper function, we need to accept this parameter in the wrapper code. The possible structure is as follows:
def func(args):
CODE.... #Code if any required.
tmp_para=args #Use tmp to accept additional parameters args
def wrapper():
extra_para=tmp_para #Implement additional parameters args to be passed to the wrapper function.
CODE... #The code of the wrapper function.
return wrapper
CODE.... #If it exists, this part of the code can be related to the processing parameter s
# The calling method is as follows:
wrapper=func(args) #args is the additional parameters to be passed
wrapper(*args,**kwargs) #They are the parameters of the wrapper itself
**In the above two cases, we have achieved **:
A. By assigning fn=deco(fn), the function of the function fn is expanded without changing the source code of the function.
B. By assigning wrapper=func(args), use the new function func to pass additional parameters to the wrapper function, but the source code of the wrapper function must be modified. If the source code of the wrapper function cannot be modified, then pass the additional parameters to What's the point of wrapper?
Let's look at an example:
#! /usr/bin/env python
# - *- coding:utf-8-*-
# Author: PandaEye
def welcome(name): #A very simple function.print("Welcome to my blog: %s !"% name)
def wrapper(gift):
ext_para=gift #Extra parameter is : gift , pass it to function deco.
def deco(fn): #The deco extend the function and no change the code of fn.
def fun(*args,**kwargs):print("I am the new function, send you 10 points more for congratulations!")fn(*args,**kwargs)print("Congratulations, you got the 1st, send the gift %s to you !"% ext_para)return fun
return deco
deco=wrapper("BMW")
welcome=deco(welcome)welcome("XiaoMa")
In the above example, the calling method of the function welcome in the main program has not changed, but the function has been expanded twice:
Among them, the deco function is used for extension for the first time.
On the basis of the first expansion of deco, we need to pass additional parameters gift to deco, which obviously cannot be passed to deco directly, because the parameter accepted by deco must be fn, so we use the wrapper function to pass it. Pass the parameter to After deco, we modified deco, because deco has to process the incoming parameters, so we must modify the code of deco. So far, two expansions have been completed.
After understanding the above process, you actually understand the decorator function, decorator function:
The decorator function actually turns the assignment code of the above two lines into @wrapper("BMW"), and then adjusts the position. For the writing process of the decorator function.
The following is the commonly used wording of the decorator in the above example. The two are very similar. After understanding the above call, you can understand this decorator function.
#! /usr/bin/env python
# - *- coding:utf-8-*-
# Author: PandaEye
def wrapper(gift):
ext_para=gift #Extra parameter is : gift , pass it to function deco.
def deco(fn): #The deco extend the function and no change the code of fn.
def fun(*args,**kwargs):print("I am the new function, send you 10 points more for congratulations!")fn(*args,**kwargs)print("Congratulations, you got the 1st, send the gift %s to you !"% ext_para)return fun
return deco
# deco=wrapper("BMW")
# welcome=deco(welcome)
@ wrapper("BMW") #This statement has the same effect as the two statements immediately above, which is a common expression of decorator functions,Before calling the decorator function, it must be defined first, so the wrapper function definition must be before this sentence, otherwise an error will be reported
def welcome(name): #A very simple function.print("Welcome to my blog: %s !"% name)welcome("XiaoMa")