Closures in Python

Source: Internet
Author: User
Tags stdin

Today, a colleague said closures, checked the closure in Python, see the following text, record for reference:

The concept of closures is involved in many languages, and this article focuses on closures in python. The use of closures in Python is primarily used for functional development.

One, define

Closures in Python are defined (interpreted) as: if, in an intrinsic function, a reference is made to a variable in an outer scope (but not at the global scope), the intrinsic function is considered a closure (closure). This definition is relatively straightforward, well understood, Unlike other definitions, the academic tastes are full (those who explain the meaning of a noun are filled with a bunch of other strange nouns that are not suitable for beginners). Here is a simple example to illustrate.

>>>def ADDX (x):>>> def adder (y): return x + y>>> return adder>>> c = ADDX (8) ;>> type (c) <type ' function ' >>>> c.__name__ ' adder ' >>> C (10) 18

Combine this simple code and definition to illustrate closures:

If in an intrinsic function: Adder (y) is the intrinsic function,

A reference to a variable that is in an outer scope (but not at the global scope): X is the referenced variable, x is inside the outer scope addx, but not in the global scope,

Then this intrinsic function adder is a closure.


A little more elaborate explanation is that the closure = function Block + the environment when defining the function, Adder is the function block, X is the environment, of course, this environment can have many, more than a simple x.

Second, use closure considerations

1, the outer scope of the local variable cannot be modified in the closure

>>> def foo (): ... m = 0 ...         Def foo1 (): ... m = 1 ... Print m ... print m ... foo1 () ... print m...>>> foo () 010

As can be seen from the execution result, although a variable m is defined in the closure, it does not change the local variable m in the outer function.

2, the following code is a classic error code when using closures in Python

def foo (): a = 1 def bar (): a = a + 1 return a return bar

This procedure is intended to be done by incrementing the variable a every time the closure function is called. But in actual use

>>> C = foo () >>> print C () Traceback (most recent call last): File ' <stdin> ', line 1, in <modul e> File "<stdin>", line 4, in barunboundlocalerror:local variable ' a ' referenced before assignment

This is because Python imports all of the closure function bar () to parse its local variables when executing code c = foo (), and the Python rule specifies that all variables on the left side of the assignment statement are local variables, and in the closure bar (), the variable A is at the left of the assignment symbol "=", is considered by Python to be a local variable in bar (). The next time you execute print C (), the program runs to a = a + 1 o'clock, because a has previously been attributed to a local variable in bar (), so Python will find the value of a in bar () to the right of the assignment statement, and the result will be an error if it is not found. 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 somewhat uncomfortable to use, so after python3, before a = a + 1, use the statement nonloacal A, which explicitly specifies that a is not a local variable of the closure.

3, there is also a prone to error cases are often mentioned in the introduction of Python closure, I have never felt that this error and closure has much to do with the relationship, but it is indeed in Python functional programming is easy to make a mistake, I would like to introduce here. Let's look at the following code

For I in range (3): Print I

In the program, this kind of loop is often present, the problem of Python is that, when the loop is over, the temporary variable i in the loop body will not be destroyed, but continue to exist in the execution environment. Another python phenomenon is that Python's function is only executed to find the value of the variable in the function body.

Flist = []for i in Range (3): def foo (x): print x + i flist.append (foo) for F in Flist:f (2)

Some people may think that the result of this code should be 2,3,4. But the actual result is 4,4,4. This is because Python has not assigned a value to I when I add a function to the Flist list, only when it is executed, and then to find the value of I, at the end of the first for loop, the value of I is 2, so the result of the above code 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, someone has to ask, what is the use of this closure in the actual development? Closures are mainly used in the functional development process. The following are the main uses of two types of closures.


Use 1, when the closure is finished, still can maintain the current operating environment.

For example, if you want the result of each execution of the function, it is based on the last running result of the function. I illustrate this with an example of a board game like this. Assuming the checkerboard size is 50*50 and the upper-left corner is the coordinate system origin (0,0), I need a function that receives 2 parameters, namely direction (direction), step (step), which controls the movement of the pieces. The new coordinates of the chess piece movement are in addition to the direction and the step length, of course, according to the original coordinate point, the closure can be used to maintain the original position of the piece of the coordinates.

origin = [0, 0]  #  coordinate system origin point legal_x = [0, 50]  #  Legal coordinates of the x-axis direction legal_y = [0, 50]  # y axis def create (pos=origin):     def player (Direction,step):        #  Here should first judge the legitimacy of the parameter direction,step, such as direction can not be inclined to walk, step can not be negative         #  Then also to the new generation of x, y coordinates of the legitimacy of the judgment, here is mainly to introduce closures, it is not written 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 cannot be written  pos = [new_x, new_y], for the reasons mentioned above         return  pos  &nBsp; return playerplayer = create ()   #  Create a pawn player, starting at Origin Print player ([ 1,0],10)   #  Move 10 steps to the positive x-axis print player ([0,1],20)   #  move 20 steps in the positive direction of the y-axis print  Player ([ -1,0],10)   #  move 10 steps in negative direction to x-axis

Output to

[10, 0] [10, 20] [0, 20]


use 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 according to this variable to show a different function. 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 in lines if keep in i] return Filter_doc return The_filter

If we need to get a line with the "pass" keyword in the file "Result.txt", you can use the example program like this

Filter = Make_filter ("pass") Filter_result = Filter ("Result.txt")

The above two usage scenarios, with object-oriented also can be very simple implementation, but in Python for functional programming, the closure of data persistence and configuration to produce different functions, it is very helpful.

Closures in Python

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.