Closures (closure) are an important syntactic structure for functional programming, and Python also supports this feature, and the following is the introduction of closures in Python.
First look at the concept of closures: closures (Closure) are short for lexical closures (Lexical Closure) and are functions that reference free variables. This quoted free variable will exist with this function, even if it has left the environment in which it was created. Therefore, closures are entities that are composed of functions and their associated reference environment.
Look at the namespace in Python before you begin to introduce closures.
The namespace in Python
Python provides namespace to identify functions/methods, variables and other information, a total of three kinds of namespace, respectively:
- Local namespace: The scope is the current function or class method
- Global namespace: Scope is current module
- Build-in namespace: Scope of action for all modules
When the name of the function/method, variable, and other information occurs, Python searches for the elements required by the user in the order of "local namespace, global namespace, build-in namespace" . and the first namespace to find this element will prevail.
At the same time, the built-in functions in Python locals () and Globals () can be used to view the elements defined in different namespace.
See an example:
s ="string in global"Num= 99defNumfunc (A, b): Num= 100Print "print S in Numfunc:", SdefAddfunc (A, B): s="string in Addfunc" Print "print S in Addfunc:", SPrint "Print num in Addfunc:", NumPrint "locals of Addfunc:", locals ()Print return "%d +%d =%d"% (A, B, a +b)Print "locals of Numfunc:", locals ()Print returnAddfunc (A, B) Numfunc (3, 6) Print "Globals:", Globals ()
The result of the above code is:
In the code, the elements defined in different namespace are obtained through locals () and Globals (), and when the s variable is accessed in the "Numfunc" function, S is found in the global because it is not defined in the local namespace; The local namespace of "Addfunc" has s, so it can be used directly.
Python Create closures
Here's an example of how Python can implement closures, step-by-step.
An example of a closure
Here is a simple example of a closure, which defines a function "greeting_conf" that can be configured to greet, in which a "greeting" embedded function is embedded:
defgreeting_conf (prefix):defGreeting (name):Printprefix, namereturnGreeting Mgreeting= Greeting_conf ("Good Morning") mgreeting ("Wilber") mgreeting (" would")Printagreeting= Greeting_conf ("Good afternoon") agreeting ("Wilber") agreeting (" would")
The result of the code is:
The above code has several points of note:
- The "greeting" function accesses the non-local variable "prefix", which is completely legal according to the previous namespace's introduction.
- The variable "prefix" is not destroyed as the function exits, but the life cycle is extended.
Let's see why the variable "prefix" Life cycle has been extended?
__closure__ Property
In Python, the function object has a __closure__ property, and we can look at some details of the closure with this property.
defgreeting_conf (prefix):defGreeting (name):Printprefix, namereturnGreeting Mgreeting= Greeting_conf ("Good Morning") Printdir (mgreeting)PrintMgreeting.__closure__PrintType (mgreeting.__closure__[0])PrintMgreeting.__closure__[0].cell_contents
As seen through the __closure__ property, it corresponds to an object that contains the cell type inside a tuple,tuple.
For this example, you can get the value of the cell (content) as "Good Morning", which is the value of the variable "prefix".
The principle of closure can be seen here, and when the inline function references a variable in the function that contains it, the variables are stored in the __closure__ property of the enclosing function and become enclosing Part of the function itself; that is, the life cycle of these variables will be the same as the enclosing function.
Closures and functions
Closures are just like functions in the form of expressions, but are not actually functions.
defgreeting_conf (prefix):defGreeting (name):Printprefix, namereturnGreeting Mgreeting= Greeting_conf ("Good Morning") Print "function name is:", mgreeting.__name__Print "ID of mgreeting is:", ID (mgreeting)Printagreeting= Greeting_conf ("Good afternoon") Print "function name is:", agreeting.__name__Print "ID of agreeting is:", ID (agreeting)
As you can see from the results of the code, a closure can have multiple instances at run time, and a combination of different reference environments (here is the prefix variable) and the same function (here is greeting) can produce different instances.
How to create a closure in Python
Creating a closure in Python can be attributed to the following three points:
- The closure function must have an inline function
- Inline functions need to refer to variables in the first level namespace of the nested function
- The closure function must return an inline function
With these three points, you can create a closure and not think of the Python decorator described in the previous article. Yes, the Python decorator is using closures.
Summarize
This article describes how to create a closure through Python, and how a closure created by Python works.
Closures in Python