Generally speaking, the concept of closures is involved in many languages, and this article focuses on the definition of closures in Python and the related usage. The use of closures in Python is primarily used for functional development. Detailed analysis is as follows:
I. Definition
The closures in Python are defined in terms of representation (interpretation) as: If a variable in an external scope (but not in the global scope) is referenced in an intrinsic function, then the intrinsic function is considered a closure (closure). The definition is relatively straightforward and understandable, It's not as pedantic as any other definition (the scholarly-tasting explanations are filled with a whole bunch of other strange nouns that are maddening in the interpretation of a noun, not for beginners). Here is a simple example to illustrate.
>>>def ADDX (x):
>>> def adder (y): return x + y
>>> return adder
>>> C = AD DX (8)
>>> type (c)
<type ' function ' >
>>> c.__name__
' adder '
>> > C (18)
Combine this simple code and definition to illustrate closures:
If in an intrinsic function: Adder (y) is the intrinsic function,
Reference to a variable in an external scope (but not in the global scope): X is the referenced variable, x is in the external scope addx, but not in the global scope,
Then the internal function adder is a closure.
A little more elaborate explanation is that closure = function Block + when defining the function of the environment, Adder is the function block, X is the environment, of course, this environment can have many, more than a simple x.
Second, the use of closure considerations
1. a closure is a local variable that cannot be modified in an external scope .
>>> def foo ():
. m = 0
... Def foo1 ():
. m = 1
... Print m ...
... Print m ... Foo1 () ... Print m ...
>>> foo ()
0
1
0
It can be seen from the execution result that although a variable m is also defined in the closure, it does not change the local variable m in the external function.
2. The following code is a classic error code for using closures in Python
def foo ():
a = 1
def bar ():
a = a + 1 return
a return
bar
The intent of this program is to increment the variable a by each time the closure function is invoked. But when it is actually used
>>> C = foo ()
>>> print C ()
Traceback (most recent call last):
File "<stdin>", Lin E 1, in <module>
File "<stdin>", line 4, in bar
unboundlocalerror:local variable ' a ' referenced bef Ore assignment
This is because when code C = foo () is executed, Python will import all of the closure function Body Bar () to analyze its local variables, the Python rule specifies that all variables to the left of the assignment statement are local variables, and in the closure bar (), variable A is on the left of the assignment symbol "=". is considered a local variable in bar () by Python. And then when you execute Print C (), the program runs to a = a + 1 o'clock because it has been previously classified as a local variable in bar (), so Python will find the value of a on the right side of the assignment statement in bar (), and the result will be an error. The solution is simple.
def foo ():
a = [1]
def Bar ():
a[0] = a[0] + 1 return
a[0] return
bar
Just set a as a container. This is a bit uncomfortable to use, so after python3, before a = a + 1, you can use the statement nonlocal A to explicitly specify that a is not a closed-packet local variable.
3. There is also an error-prone case that is often mentioned when introducing the Python closure, I have never felt that this error has much to do with closures, but it is a mistake that is easy to make in Python functional programming, and I might as well introduce it here. Let's look at the code below.
For I in range (3):
Print I
This kind of loop is often found in the program, and the problem with Python is that when the loop is over, the temporary variable i in the loop body is not destroyed, but continues to exist in the execution environment. Another python phenomenon is that Python functions are only executed to find the values of variables in the function body.
Flist = [] for
I in range (3):
def foo (x): print x + i
flist.append (foo) to
F in flist:
F (2)
Some people may think that the code should be 2,3,4. But the actual result is 4,4,4. This is because when the function is added to the Flist list, Python has not given me a value, only when executing, to find what the value of I, when the first for loop after the end of the value of I is 2, so the above code execution result is 4,4,4.
The solution is also very simple, rewrite the definition of the function can be.
For I in range (3):
def foo (x,y=i): print x + y
flist.append (foo)
Third, the role
Having said so much, some people have to ask, what is the use of this closure in actual development? Closures are mainly used during functional development. The two main uses of closures are described below.
Usage 1: When the closure is completed, the current operating environment can still be maintained.
For example, if you want the results of each execution of a function to be based on the last run of the function. I'm going to illustrate it with a chess-like game example. Assuming the chessboard size is 50*50 and the upper-left corner is the coordinate system origin (0,0), I need a function that receives 2 parameters, respectively, the direction (direction), the step, and the function controls the movement of the pieces. The new coordinates of the piece movement in addition to relying on the direction and step, of course, according to the original coordinates point, with the closure can maintain the original coordinates of the piece.
Origin = [0, 0] # Coordinate system origin
legal_x = [0] # The legal coordinates of x axis direction
legal_y = [0, M] # y-Axis legal coordinates
DEF create (pos=origin):
def player (Direction,step):
# Here we should first judge the legality of the parameter direction,step, such as direction not to walk diagonally, step cannot be negative,
and then also to the newly generated x, Y-coordinate the legality of judgment processing, here is mainly to introduce closures, do not write in detail.
new_x = pos[0] + direction[0]*step
new_y = pos[1] + direction[1]*step
pos[0] = new_x
pos[1] = new_y
> #注意! This can not be written as a pos = [new_x, new_y], as mentioned above, return
POS return
player
= Create () # Creates a pawn player, starting
with the origin Print player ([1,0],10) # Moves the 10-step print player ([0,1],20) # to the x-axis in positive direction
to move the 20 step
print player ([ -1,0],10) # Move 10 steps in the negative direction of the x-axis.
The output is:
Usage 2: Closures can be based on the external scope of local variables to get different results , which is a bit like a configuration function, we can modify the external variables, closures based on this variable to show different functions. For example, sometimes we need to analyze the special lines of some files to extract these special lines first.
def make_filter (keep):
def the_filter (file_name):
file = open (file_name)
lines = File.readlines ()
File.close ()
filter_doc = [I for i ' lines if keep in i] return
filter_doc return
the_filter
If we need to get the line with the "pass" keyword in the file "Result.txt", you can use the example program
Filter = Make_filter ("pass")
Filter_result = Filter ("Result.txt")
Both of these scenarios can be easily implemented with object-oriented, but it is helpful to have the data persisted and configured to produce different functions in Python when functional programming is in use.
It is believed that this article has certain reference value to everyone's Python programming.