1. Preliminary knowledge for implementing decorators
Decorator = higher order function + cold element nesting + closure
1. Definition of high price function:
1. The parameter received by the function is a function name
2. The return value of the function is a function name
3. Any one of the above conditions can be called a higher-order function
Example 1: Foreshadowing
1 import time 2 #Example 1 3 def fn(): 4 print ( ' This is the called function ' ) 5 time.sleep(2 ) 6 7 def test(func): 8 print ( ' The higher-order function is about to start running ' ) 9 start_time = time.time() 10 func() 11 end_time = time.time() 12 print ( ' The running time of the called function %s ' %(end_time - start_time)) 13 14 test(fn)
Example 2
1 #Example 2 2 import time 3 def fn(): 4 print ( ' This is the called function ' ) 5 time.sleep(2 ) 6 def test(func): 7 print ( ' Executing a higher-order function ' ) 8 return func 9 #The first call 10 f = test(fn) 11 print (f) 12 f() 13 14 # # The second call, upgraded version: assign the return value of the calling function test(func) to a The variable fn with the same name as the called function fn(), the final effect is 15 # (1) Do not change the source code of the called function fn() 16 # (2) Do not change the calling method of the called function fn() 17 fn = test(fn) 18 print (fn) 19 fn()
1 is executing a higher order function 2 <function fn at 0x0000017065C999D8> 3 this is the called function 4 is executing a higher order function 5 <function fn at 0x0000017065C999D8> 6 this is the called function
Upgraded version: assign the return value of the calling function test(func) to a variable fn with the same name as the called function fn(), the final effect is
( 1) does not change the source code of the called function fn()
( 2) Does not change how the called function fn() is called
Example 3 The result of this situation is that one more line is run
1 #Example 3 2 import time 3 def fn(): 4 print ( ' This is the called function ' ) 5 time.sleep(2 ) 6 7 def test(func): 8 print ( ' Start executing the calling function ' ) 9 start_time = time.time() 10 func() 11 end_time = time.time() 12 return func #The result of this situation is that one more line is run 13 14 fn = test(fn) 15 fn()
1 start executing the calling function 2 this is the called function 3 this is the called function
Example 4
1 #Example 4 2 def fn(): 3 print ( ' This is the called function ' ) 4 def test(func): 5 print ( ' The higher-order function is being executed ' ) 6 res = func() 7 print ( ' The The calling function is executed ' ) 8 return res 9 10 fn = test(fn) 11 # fn() # Error: TypeError: 'NoneType' object is not callable
1 The higher-order function is being executed 2 This is the called function 3 The called function has finished executing
Even if a value is assigned, it still cannot solve the result of printing one more line. So a single layer function can't solve this problem
2. Nested functions