In python, the role of the decorator is to add decoration to the function without changing the function itself. Let's take an example first.
def outer(func): #decoration function def inner(): print("before") func() print("after") return inner def f1(): #The decorated function print("fffff") f1 = outer(f1) f1 ()
Implementation process:
The outer function is found, the internal structure is not executed, and the memory is thrown
Find the f1 function, do not execute the internal structure, throw memory
Execute the outer function parameter is the f1 function name
Enter the outer function, find the inner function, do not execute the internal structure, throw the memory
Execute return to return the function name of the inner function
From the outer function, assign the inner function name to the function name of the f1 function
Calling the f1 function here is actually executing the inner function (the previous step)
Enter the inner function and output before
Call func() The func parameter is the name of the f1 function passed in, so f1() is actually called
Enter the f1 function body and output fffff
Exit the f1() function and continue to execute the output after
end
As can be seen from this example, without changing the internal structure of the f1 function, it can still output before after when we call f1
Equivalent to decorating the f1 function
And our above code can be rewritten as
def outer(func): def inner(): print("before") func() print("after") return inner @outer def f1(): print("fffff") f1 ()
is equivalent to the first code
@outer is done
f1 = outer(f1)
It is easy to write. In fact, it is all @+ decorated functions (not decorated functions!!!) Put it on the previous line of the decorated function
We execute the f1 function, which is to execute the inner function in the decorated function
Replenish
1. Some people here may have doubts. It is so troublesome. I can just write it directly into the f1 function.
My explanation here is the development closure principle
In simple terms, it stipulates that the functional code that has been implemented is not allowed to be modified, but can be extended, namely:
- Closure: Implemented functional code block
- Open: The specific details of extension development will not be discussed in this article (because I also understand the surface, don't care about the details~)
2. If the function has no return value, the default returns None
If the above code returns inner() in the decorator function outer
will execute inner() and then the inner function returns None with no return value
return None
So you can't add () here, it's just the assignment of the function name
When func() is executed, f1() is executed here, which is the original f1() because it is the func() whose function name is changed after you pass f1 to the formal parameter and then call func()
Go back and watch it again and you'll understand~
Second shot~
def outer(func): def inner(): print("before") i = func() print("after") return i return inner @outer def f1(): print("fffff") return "OK" f1()
Unlike the second source code, this decorated function has a return value. The purpose of our decorator is to decorate the function without changing the function itself.
And our decorated function returns ok so we want to make it bold
Of course we cannot write
def inner(): print("before") return func() print("after") return innerprint("after") will not be executed