First, the adorner:
The adorner, in this case, means a function, that is, a decorative function. function is to add a new function to other functions, it can not change the original function, the original function and the original is exactly the same, nothing needs to change, just need to add the function outside the call which adorner can be, the role of the adorner is not to change the original function of the call, do not change the original function of the code, Adds a new feature to it. But does not change the function, adds the new function to it, that is impossible, the adorner just secretly changed the original function, but the original function unconsciously.
Learn the pre-Decorator knowledge Reserve:
1, function is a variable, in Python function is a variable, function name is the variable name, function in the name of the memory address. It puts the function body in memory and runs the function from the memory address in the function name at the time of invocation. The function name is called with parentheses, and only the function name is the memory address of the print function.
def Test (): int (input ('Please enter your age:'))
Test ()
Print (test)
Operation Result:
Please enter your age:20<function test at 0x02a84270>
2, high-order function, if the function of the entry is a function, then this function is a higher-order function.
3, function nesting, function nesting is to define a function in the function, rather than call a function.
defA (a):Print("I am A") defB (b):Print("a+b=", A +b)Print("I am B") B (2) Print("OVER !!!") A (3)
With this knowledge, let's write a simple decorator to count the function run time.
Import time
def fun ():
Time.sleep (3)
Print (' In the fun ')
def test (func):
Start_time = Time.time ()
Func ()
Stop_time = Time.time ()
Print (' The Func run time is%s '% (stop_time-start_time))
Test (Fun)
Operation Result:
1 inch the Fun 2 is 3.007230520248413
But in that case, we're going to pass a function as an argument to the Test1 function every time. Changed the way the function was called before executing the business logic, running Bar (), but now has to change to Test1 (bar). The decorator is used at this point. We're going to figure out a way to do this. Do not modify the calling code, and if you do not modify the calling code, it means that calling bar () requires the effect of calling Test1 (bar). We can think of assigning test1 to bar, but Test1 seems to have a parameter ... Think of ways to unify the parameters! If Test1 (bar) does not directly produce a call effect, but instead returns a function that is consistent with the Foo argument list ... It's good to have the return value of Test1 (bar) assigned to bar, and then the Code calling bar () does not have to be modified at all!
Import TimedefTime (fun):defdeco (): Start_time=Time.time () fun () Stop_time=time.time ()Print('The func run time is:%s'% (Stop_time-start_time)) returnDeco@timedefdos (): Time.sleep (2) Print('In the dos') DOS ()
Operation Result:
in is: 2.0002448558807373
In this way, we increase the reusable nature of the program, which can be called directly when other functions need to invoke the adorner. The adorner is so handy in python that the functions that are attributed to Python can be passed as arguments to other functions as normal objects, and can be assigned to other variables, which can be used as return values and can be defined within another function.
1 Import Time2 3 defTiming (fun):4 5 defDeco (*ARG, * *kwarg):6 7Start_time =time.time ()8 9Fun (*arg, * *Kwarg)Ten OneStop_time =time.time () A - Print('The func run time is:%s'% (Stop_time-start_time)) - the returndeco - - @Timing - defTar (name, age): + -Time.sleep (2) + A Print('In the tar:', name, age) at -Tar'HK', 18)
Operation Result:
1 in the TAR:HK2 is: 2.000657081604004
Python decorators, generators, built-in functions, JSON