1. Closure appreciated
We closures may be understood as a special function, such a function is a function of two nested composition, and the function and the function is called an outer, external function returns a reference to the function, in which case it constitutes Closure.
2. Closure format
Closure is described below in pseudo-code format
def outer function (parameter): def inner function (): Print ( " inner function execution " parameters) return the inner function inner function REFERENCE = outer function ( " pass parameters " ) inner layer function quote ()
The outer function parameters, does not have to, according to the circumstances, but in general there will including the function and to use
Case
def func(a, b): def line(x): return a * x - b return line line = func(2, 3) print(line(5))
7 The results obtained
in this case, there is an outer function func reception parameters a = 2, b = 3, the line receiving function parameter x = 5, the inner body of a function calculated value a * xb i.e. as 2 × 5-3 the return value, the function returns a function of the outer reference herein means that a function of the line start address in memory, the function calls the final line () returns the value obtained 7
3. Modify the function values outside the function
Usually at the end of the function, and will release the temporary variable, but in the closure, due to the function of the outer temporary variables used in the function of the inner, outer case and the temporary variables will function to bind together to function, so that although the external function over, but when calling within the function still be able to use temporary variables, namely the closure of the outer layer parameters can be retained in memory
if you want to modify the value of the inner function outside the function, you need to use nonlocal keyword to declare variables
def func(a, b): def line(x): nonlocal a a = 3 return a * x - b return line line = func(2, 3) print(line(5))
In this case run results: 12
python face questions:
Python face questions: What will the following code output?
def testFun(): temp = [lambda x : i*x for i in range(4)] return temp for everyLambda in testFun(): print (everyLambda(2))
I thought silently brain, it goes without saying it, certainly:
0,2,4,6
However Goose correct answer:
6,6,6,6
the reason:
Late Python bindings closures caused by late binding, which means that variable in the package is closed inside look at the time the function is called. So the result is that when any testFun () function returns is called, at that time, the value of i is around the role when it was called the domain lookup, then, the function returns regardless of which is called, for all loop has been completed, the value of i *** 3 is, therefore, the value of the function is returned for each testFun 3. Thus a value equal to 2 or more is transmitted into code that returns a value 6 (for example: 3 x 2)
How to solve it? ?
1: Creating a closure, by using the default parameter binding its parameters immediately
def testFun(): temp = [lambda x ,i=i: i*x for i in range(4)] return temp for everyLambda in testFun(): print (everyLambda(2))
2: Use functools.partial function, the function of certain parameters (whether or not the default value) to fixed (i.e. equivalent to setting default values)
from functools import partial from operator import mul def testFun(): return [partial(mul,i) for i in range(4)] for everyLambda in testFun(): print (everyLambda(2))
3: elegant wording generator directly
def testFun(): return (lambda x ,i=i: i*x for i in range(4)) for everyLambda in testFun(): print (everyLambda(2))
4: Thought using lazy evaluation of yield
def testFun(): for i in range(4): yield lambda x : i*x for everyLambda in testFun(): print (everyLambda(2))