Closure problem for python functions (internal and external functions detailed)

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

Keywords: Python

Added by abhishekphp6 on Mon, 10 Feb 2020 19:32:08 +0200