What is a closure?
To paraphrase the wiki: in Computer science, closures (Closure) are abbreviations for lexical closures (lexical Closure) and are functions that refer to free variables. The referenced free variable will exist with this function, even if it has left the environment that created it. So, there is another saying that closures are entities that are combined by functions and reference environments associated with them. Closures can have multiple instances at run time, and different reference environments and the same combination of functions can produce different instances.
Well, looking at this definition is not yet an immediate understanding of what closure is. However, closures are not difficult to understand, and looking down on a few small examples will make it clear what it is.
Introduction of the premise:
Before we know about closures, we need to understand the scope of the variables in the Python syntax (useful for understanding the examples of the following closures). Python supports multiple function nesting from syntax. Under Python's existing (2.1-version) nesting rule, nested functions can access the local scope of the global scope itself and the functions on its own. such as (from the Python Core programming book):
Variable Range Example one:
x = 1
def foo ():
y = 2
def bar ():
z = 3
Print x + y + Z
Bar ()
Foo ()
Result is output: 6
Explain:
That is, the bar () function can access global variable x, its own local scope Z, and also access the local variable y of the nested foo () function.
Next, we need to know that in python2.x, the inner function, while having access to the variables of the outer function, cannot be assigned a value. We make a slight change to the example:
Variable Range Example two:
x = 1
def foo ():
y = 2
def bar ():
z = 3
Y + 1
Print x + y + Z
Bar ()
Foo ()
Results: the error "unboundlocalerror:local variable ' y ' referenced before assignment" is now running.
This error means that the local variable y is not defined before the reference. This is because when you assign a variable in the inner function, Python will think that the variable is local, so if the value of the modified variable becomes a local variable (of course, if not modified, then Python will first look in the scope of its definition, and if not, go to the outer layer to find it, So you know that Y is an outer variable.
This can be solved using nonlocal in Python 3.x, where the nonlocal keyword is used to use an outer (non-global) variable in a function or other scope.
With a look at the scope of variables in Python, let's look at a couple of closures (from the Python Core programming book):
Closure Example One:
def counter (start_at=0):
Count = [Start_at]
Def incr ():
COUNT[0] + + 1
return count[0]
Return INCR
Results:
>>> count = Counter (5)
>>> Print count ()
6
>>> Print count ()
7
>>> Count2 = counter (100)
>>> Print Count2 ()
101
Explain:
In the counter function, we define a incr function, the function of the INCR is to add the value of count[0 to one, and the counter function returns the INCR function. Note that all the order objects in Python can also be passed and returned as function objects.
When we execute Count = Counter (5), Count is given the INCR function object, which means that the call to count is equivalent to calling the INCR function. In addition, we give the counter function an argument of 5, then the initial value of Count[0] is 5, assigning the function object that returns the given parameter to count, then each call count executes Count[0] plus one, and returns the value of Count[0].
In summary, we can see that the counter () function has different parameters, the resulting function object is not the same, that is, we can use this form to bind the function and a parameter together to assign value to an object, and then through the object for the relevant operation.
Note: You cannot change the count in counter () from a list to a single variable, or you will report a unboundlocalerror error (the premise explains why), but the list is OK.
Closure case Two:
def xy_add (x):
def adding (y):
#根据前面的函数嵌套变量作用域介绍, you should know that adding () can access X
return x + y
Return adding
Results:
>>> Myadd = Xy_add (3)
>>> print Myadd (4)
>>> print Myadd (3)
Explain:
The Xy_add () function adding the scope of its nested function object, and when we give a xy_add () function argument, such as a given XI, and assign the function object returned under this parameter to Myadd, the Myadd is a function with a specific parameter, by calling Myadd (Yi We can get any sum of Xi and Yi
Python instance
It's always a little confusing to look at the concept, so just look at a few Python examples.
Example 1
def make_adder (addend):
def adder (augend):
return augend + addend
Return adder
p = Make_adder (23)
Q = Make_adder (44)
Print P (100)
Print Q (100)
Run Result:
123
144
Analyze:
We found that the Make_adder is a function, including a parameter addend, the special place is that this function also defines a new function, the new function inside a variable is exactly the external make_adder parameters. In other words, The externally passed Addend parameters have been bound together with the Adder function, forming a new function, we can see addend as a new function of the configuration information, configuration information is different, function is not the same, that is, can be customized after the function.
Looking at the results of the run, we found that although P and Q were make_adder generated, different results were obtained because the configuration parameters were different and then the function of the same parameter was followed. This is the closure.
Example 2
def hellocounter (name):
COUNT=[0]
Def counter ():
Count[0]+=1
print ' Hello, ', Name, ', ', str (count[0]) + ' access! '
Return counter
Hello = Hellocounter (' ma6174 ')
Hello ()
Hello ()
Hello ()
Execution results
Hello, YSISL, 1 access!
Hello, YSISL, 2 access!
Hello, YSISL, 3 access!
Analyze
This program is interesting and we can think of this as a function that counts the number of times a function is called. Count[0] can be seen as a counter, the Hello function is not executed once, and the value of count[0] is added 1. Maybe you have a question: Why not write count directly and use a list? This is a bug in Python2, and if you don't use a list, you'll report an error:
Unboundlocalerror:local variable ' count ' referenced before assignment.
What do you mean by that? conut this variable you have no definition of the direct reference, I do not know what it is, the program crashed. So, again python3 inside, introduced a keyword: nonlocal, what is this keyword? is to tell the Python program, My count variable is externally defined, so go outside and look for it. Then python goes to the outer function and finds the COUNT=0 definition and assignment, and the program executes normally.
Python3 Code
def hellocounter (name):
Count=0
Def counter ():
nonlocal count
Count+=1
print ' Hello, ', Name, ', ', str (count[0]) + ' access! '
Return counter
Hello = Hellocounter (' ma6174 ')
Hello ()
Hello ()
Hello ()
Example 3
def makebold (FN):
Def wrapped ():
Return "<b>" + fn () + "</b>"
return wrapped
def makeitalic (FN):
Def wrapped ():
Return "<i>" + fn () + "</i>"
return wrapped
@makebold
@makeitalic
def hello ():
Return to "Hello World"
Print Hello ()
Execution results
<b><i>hello world</i></b>
Simple analysis
What do you think? Is this program familiar? Isn't this a legendary decorator? Yes, this is the adorner, in fact, the adorner is a closure, we recall the concept of the adorner: function (parameters, return value, etc.) for processing, to generate a function enhanced version of a function. And looking at the concept of closures, this enhanced version of the function is not what we configure after the function? The difference is that the adorner's argument is a function or class that specializes in processing a class or function.
Python inside a lot of advanced features, such as adorners, generators, list push, closures, anonymous functions, and so on, the development of use, may achieve a multiplier effect!
of the sum.
Meaning and function:
To tell you the truth, I'm a beginner of Python, and I haven't used any closures yet, but I'm not impressed by JavaScript. Here are excerpts from other people's views on the Internet.
The fundamental purpose of 1> functions and objects is to organize code in some logical way and to improve the reuse of code. Closures are also the structure of an organization's code, which also increases the reusable nature of code. Source.
2> can still maintain the current operating environment when the closure is completed. For example, when controlling the movement of a piece, the closure can be calculated using the coordinates of the last piece. Source.
3> closures can produce different results depending on the local variables of the external scope, which is a bit like a configuration function, and we can modify the external variables, which show different functions according to the variable. For example, sometimes we need to analyze the special lines of some files to extract these special lines first. Source.
4> is beneficial to parallel operation, analogy adorner function and so on.