Advanced function (closure)

Closure

  • Closure function meaning: 1 internal function to reference an external function returns a variable 2. a function from the inside to the global value
  • Is simply a function definition is referenced outside the function defined variables, and the function may be performed outside the defined environment. We call such a closure function. In fact closures can be seen as a more generalized concept of function. Because it no longer functions defined in the traditional sense.

First, an example of a small closure function:

outer_func def (): 
    loc_list = [] 
    def inner_func (name): 
        loc_list.append (len (loc_list) + 1) 
        print ( "% s% s loc_list = '% (name, loc_list)) 
    return inner_func 
clo_func_0 = outer_func () 
clo_func_0 ( 'clo_func_0') 
clo_func_0 ( 'clo_func_0') 
clo_func_0 ( 'clo_func_0') 
clo_func_0 ( 'clo_func_0') 
clo_func_1 = outer_func () 
clo_func_1 ( 'clo_func_1') 
clo_func_1 ( 'clo_func_1')

Result of the program: 

clo_func_0 loc_list = [1] 
clo_func_0 loc_list = [1, 2] 
clo_func_0 loc_list = [1, 2, 3] 
clo_func_0 loc_list = [1, 2, 3, 4] 
clo_func_1 loc_list = [1] 
clo_func_1 loc_list = [1, 2]

  This is a closure function, but variable reference is a list type, which means that this variable is a variable type, each function call, and the results will change.

Simple function with the following example:

# Magic function written 
DEF FUNC (LST = []): 
    lst.append (. 1) 
    Print (LST) 

# avoid using the default parameters of the type of variable 
FUNC () 
FUNC () 
FUNC () 
FUNC () 

# call results 
[ 1] 
[1, 1] 
[1, 1, 1] 
[1, 1, 1, 1]

 

In case closure function we can at least have the following understanding of free variables closure of references:

  • Closure free variables specific reference only and associated closure, free variables each instance of closure referenced interference.
  • Examples of a closure of its free variable modification is passed to the next invoked closure example.

For this concept to understand is not so intuitive, so when using very easy to fall into the trap.

Second, the closure traps

Trap closure function:

def my_func(*args):
    fs = []
    for i in range(3):
        def func():
            return i * i
        fs.append(func)
    return fs

fs1, fs2, fs3 = my_func()
print (fs1())
print (fs2())
print (fs3())

#运行结果
4
4
4

  The above described code is a typical example of misuse of the closure. The results of the program is not what we think the results 0,1,4. The actual results of all 4.

In this example, it is not a return my_func closure function, but a function of a list comprising three closure. All closure function in this example is rather special place is the return of all reference the same free variables defined in the parent function.

  But the question here is why the for loop variable change will affect all of closure function? In particular example we have just described in the above clearly illustrates the different instances of the same free variables referenced in the closure of each other will not be affected. And this view is absolutely correct.

  So where is the problem in the end? How should a correct analysis of the root causes of this error.

  In fact, the key problem is that before the closure list fs for the return value of a variable has changed the cycle, and this change will affect all function references its internally defined. Because of its function before the function defined inside my_func closure function returns not only inside a defined function.

  Of course, this internal variable parent function function reference is not defined in the free variable, but rather a local variable in the current block.

def my_func(*args):
    fs = []
    j = 0
    for i in range(3):
        def func():
            return j * j
        fs.append(func)
    j = 2
    return fs
f = my_func()

print(f)

#运行结果:
[<function my_func.<locals>.func at 0x00000000021107B8>, <function my_func.<locals>.func at 0x0000000002110840>,
<function my_func.<locals>.func at 0x00000000021108C8>]

  

  The above code logic is equivalent to the previous example. Here perhaps understand a little better, because before the function func defined within the actual implementation, any changes to the local variable j will affect the operating results of the function func.

  Once my_func function returns, then the function func is defined inside a closure, wherein the variable j becomes a reference only and specific free variables associated closure. Later analyzes, the free variables stored in a Cell object.

  Using lambda (lambda) expression rewrite this example:

def my_func(*args):
    fs = []
    for i in range(3):
        func = lambda : i * i
        fs.append(func)
    return fs

  

  After the above analysis, we derive a significant experience in the following: Return closure do not reference any loop variables or variable subsequent changes occur.

  Value is returned before the closure, the closure referenced in this rule on the nature of the variables defined in the parent function could not what we expect change.

def my_func(*args):
    fs = []
    for i in range(3):
        def func(_i = i):
            return _i * _i
        fs.append(func)
    return fs

#或者
def my_func(*args):
fs = []
for i in range(3):
func = lambda _i = i : _i * _i
fs.append(func)
return fs

  

  The correct approach is to assign local variable to the parent function parameter of the function. When the function is defined, different assignment parameter will remain in the current function definition, will not affect the other functions.

  Also note that there is no reference to local variable defined in the parent function if the function is returned, then the function returns closure function is not.

Closures Function: https://www.cnblogs.com/yssjun/p/9887239.html

 

 

 

 

 

 

 

 

 

 

  

 

 

 

Guess you like

Origin www.cnblogs.com/mainstream/p/11028216.html