Closure problem for python functions (embedded functions)
>>> def func1(): ... print ('func1 running...') ... def func2(): ... print ('func2 running...') ... func2() ... >>> func1() func1 running... func2 running...
The internal function func2 scope is all within the external function func1 scope
An error will be reported if an attempt is made to call an internal function outside an external function
>>> func2() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'func2' is not defined
On the closure problem of python
An internal function is considered a closure if an attempt is made to reference a variable in an internal function that does not include the external scope of the external function
>>> def FuncX(x): ... def FuncY(y): ... return x*y ... return FuncY
For FuncY functions, a reference is made to the variable x in the entire scope of the FuncX function (the external effect of the non-global scope of the FuncY function), from which the FuncY function is said to be a so-called closure.
>>> f = FuncX(8) >>> f <function FuncY at 0x7f3a436fc2a8> >>> type(f) <type 'function'> >>> f(10) 80 >>> FuncX(7)(8) 56
Since closures themselves are based on the concept of internal functions, they cannot be called from the external scope of an external function.
>>> FuncY(8) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'FuncY' is not defined
Since it is based on the concept of internal functions, it is natural for internal functions to modify variables that refer to the scope of external functions, which will start the shielding mechanism of the interpreter.
>>> def Func1(): ... x = 233 ... def Func2(): ... x *=x ... return x ... return Func2() ... >>> Func1() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in Func1 File "<stdin>", line 4, in Func2 UnboundLocalError: local variable 'x' referenced before assignment
The left value of x*=x is now a variable in the scope of an internal function, and an attempt is made to square undefined data, resulting in an error.
>>> def Func1(): ... x = 233 ... def Func2(): ... x = 321 ... return x ... return Func2() ... >>> Func1() 321
Internal functions create x variables and block x variables within the scope of external functions
Solutions before python3
Applying container types (list,tuple, etc.) to store variables in the scope of an external function will not be blocked by the shielding mechanism because container types are not stored on the stack
>>> def Func1(): ... x = [233] ... def Func2(): ... x[0] *= x[0] ... return x[0] ... return Func2() ... >>> Func1() 54289
Solution after python3: nonlocal keyword
>>> def Func1(): ... x = 233 ... def Func2(): ... nonlocal x ... x *= x ... return x ... return Func2() ... >>> Func1() 54289