Decorative Device
definition : Essentially a function, (decorating other functions) is adding additional functionality to other functions.
principle : 1. Cannot modify the source code of the decorated function
2. Cannot modify the calling mode of the decorated function
Realize the Knowledge reserve of adorners:
1. function is "variable"
2. Higher order functions (one of the following conditions is the higher order function)
-
- A: Pass a function name as a parameter to another function (modify its function without modifying the source code of the decorated function, but the calling method is changed)
- B: The return value contains the function name (does not modify the function's calling method, but modifies the function function)
3. Nesting functions
Summarize:
Higher order function + nested function = = Adorner
1. function is variable
def bar (): #这里定义个函数print (' This is bar ... ') func = Bar #将函数当变量一样赋值给funcfunc () #这是func加上 () can be used as a function
This is the function is the variable.
2. Higher-order functions
A: pass a function name as a parameter to another function (modify other functions without modifying the source code of the decorated function, but the calling method is changed)
def bar ():p rint (' This is bar ... ') bar () print ('----------------------------------') def Test (func): #在这里增加了功能print ( Func) test (bar) #但是这里修改了调用方式
B: The return value contains the function name (does not modify the function's calling method, but modifies the function function)
def bar ():p rint (' This is bar ... ') bar () print ('----------------------------------') def Test (func): # Added here the function print (func) return func# here returns the function Address bar = Test (bar) #将函数地址赋给一个变量, the variable and the passed function with the same name bar () #这个变量加上括号, it can be used when the function, Without modifying the function's invocation
3. Nesting functions
x = 1def test1 ():d EF test2 ():d EF test3 (): x = 3print (x) test3 () test2 () test1 ()
Like this, defining a function inside a function is called a nested function.
Now three knowledge points have been explained, the following first implement a original version of the adorner.
Original version Decorator
Import Timedef test1 (): #这里是被装饰的函数 time.sleep (1) print ("This is test1 ...") def timer (func): # Here is the decorator function def deco (): strat = Time.time () func () stop = Time.time () print ("Run time%s"% ( Stop-strat)) return decotest1 = Timer (test1) test1 ()
The function of this adorner is to test the run time of the Test1 function, the DECO function has this function, so here in fact I want to run the Deco function, the timer () function return value is the address of the Deco function, while the Deco function wants to run also to meet another condition, That is the need to call the timer function, only when the timer function is running when the timer function is written in order to be effective or activated, the DECO function will be defined success. To this, Test=timer (test1) This code means that the first call to the timer function to make the definition of the Deco function to take effect, at the same time will be decorated function test1 function of the address passed in, so that the function of the Func functions function, This is the timer function that returns the address of the Deco function and assigns the address to the TEST1 variable. Then the following test1 is appended with parentheses, which becomes the form of test1 () and can be run. Such an original version of the decorator was finished.
The next step is to write an example of a real decorator.
Import timedef Timer (func): def deco (): start_time = Time.time () func () stop_time = Time.time () Print (' The Func run time is%s '% (stop_time-start_time)) return deco@timer #这里等于 test = timer (test), which function to decorate, Just before which function add this def test (): time.sleep (2) print (' This is test ... ') test ()
These are some of the more basic, if the decoration has parameters of the function and the number of parameters is not necessarily what to do? Let's write a high-level case--parametric adorner.
Advanced Case-Parametric adorner
Import timedef Timer (func): def deco (*args,**kwargs): #在这里接收参数 start_time = Time.time () func (*args,** Kwargs) stop_time = Time.time () print (' The Func run time is%s '% (stop_time-start_time)) return Deco@timerdef Test (name): time.sleep (2) print (' This is test ... ', name) test (' vector ')
If the original test function has a return value, it is decorated and we print it (test ()) and the result is none. Because of the Test=deco, and Deco has no return value, it cannot be printed. This will cause a problem, if the test function has a return value, a function of the test function (the return value) will be lost.
The solution looks at the following case.
High-level case-adorner with return value
Import timedef Timer (func): def deco (*args,**kwargs): start_time = time.time () res = func (*args,**kwargs) stop_time = time.time () print (' The Func run time is%s '% (stop_time-start_time)) return res # This returns the Func return value to return deco@timerdef Test (name): time.sleep (2) print (' This is test ... ', name) Return ' ASDFASDFGDFGD ' Print (Test (' vector '))
This will allow you to print out the return value.
There are also times when we need to give the decorator a pass-through for internal use. Solution look below.
High-level case--to the adorner
Import timedef Timer (temp): print (' This was ', temp) #这里是加进来的参数 def Out (func): def deco (*args,**kwargs ): start_time = time.time () res = func (*args,**kwargs) stop_time = Time.time () print (' The Func run time Is%s '% (stop_time-start_time)) return res return deco return Out@timer (' temp ') def test (name): Time.sleep (2) print (' This is test ... ', name) return ' ASDFASDFGDFGD ' Print (Test (' vector '))
The whole is actually adding a layer of inline functions outside.
Python Learning path 6-Decorators