One, nested functions
The inside of the function defines another function, which is called the nested function, inside the function is called the inner function.
Example:
Second, return function
A function can receive a function object as a parameter, and the same function can return a function object as a return value.
Example:
The return function can be used to delay the execution of a function.
III. Namespaces and variable scopes
Variable scope refers to the scope of the variable's survival. A namespace refers to a collection of all properties (objects) that belong to an object.
Example:
A's namespace is a collection of all objects inside a function object, including the variable A, function B, and the namespace of the variable b;b is the collection of all objects that belong to function B, including the variable B;
A's variable scope is the namespace of a, and the variable scope of B is the namespace of B.
As you can see, the namespace is the entire space of the next layer of the object (for example, A's namespace is the next layer of all of a), and the variable scope is the namespace of the previous layer of the variable's layer (for example, the scope of a is the namespace of a).
Four, closed package
An intrinsic function of a nested function uses a variable other than an intrinsic function, and the nested function is called a closure.
Example:
Closures give us an important hint is that a variable can play a role in the inner function as long as it is in scope.
Five, decorative device
An adorner is essentially a function, a high-order function that returns a function, and a closure. The problem that the adorner solves is to add some new functions to the original function without changing the function of the original function.
For example, there is a function myname that prints my name:
Now I want to print the I come from Foshan without changing the myname code, so I can use the adorner:
In fact, we don't need an intrinsic function to add functionality to the incoming function:
In doing so, if we pass in func with parameters, we can do the following:
In this case, although the Func with parameters can be passed in, the newly added function is separate from the call of Func, which is also inappropriate.
So our decorator should be a function that sets the receive function, returns the function, and closes the packet, and allows the passed function with parameters:
The (*args,**kw) parameter group indicates that any parameter can be passed in.
VI, adorner operator @
After defining the adorner, we can apply the adorner to any function we want to add to the function:
In order to make the adorner more convenient to use, mainly for the code to appear more clear logic, so it defines the @ can directly invoke parameters, the use of the following:
Once the @wherefrom statement is declared before the function definition, the logic is executed when the function is called:
MyName = Wherefrom (myname)
Seven, high-level decorative device
When we define an adorner, the original function cannot be changed. If we add new parameters to our new function, how do we define this decorator? The idea is very simple, originally two layers of nested functions we have enough to write three layers on it, the first layer is used to pass in the new parameters, the second layer for the incoming function:
(Note: There is no change in the order in which the Aplace and Func are passed in, just think about why.) )
Test the effect:
The execution logic here is:
MyName = wherefrom ("Guangzhou") (myname)
The problem of the function name after decoration
Whether it is an ordinary decorator or a high-level adorner, after using the @ operator to decorate the function, the function name pointed to the specific function object is not the original function object when the call is decorated function, like above: MyName = Wherefrom (myname) and myname = Wherefrom ("Guangzhou") (myname), the function name points to the Inner function object:
But sometimes we might use a call to the name of the original function in a subsequent program, such as the above myname.__name__, in order to avoid confusion, we should consider this when the adorner is defined:
We point the name of the inner function to the name of the Func function in the case where the code of the inner function is unchanged, so can we define this new function as an adorner to be used for the other decorator definitions? Python has implemented this feature for us:
The wraps decorator in the Functools is designed to do this. Interested can look at the source code of wraps, see how this adorner implementation.
Specific reference:
1, "core Programming Second Edition" 11th chapter;
2. Liaoche-Functional programming
—————— the end of this article!
13. Functions in Python (Closures and adorners)