Closure (Python)

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)) 

 

Guess you like

Origin www.cnblogs.com/zknublx/p/11968431.html