When referring to a variable in an expression, Python will traverse each scope in the following order to find the variable:
- Current function scope
- Any peripheral scope (such as other functions containing the current function)
- global scope, that is, the scope of the module where the code is located
If the variable cannot be found in the above scope, a NameError exception will be reported.
But when assigning values to variables, the rules will be different.
- If the current scope variable already exists, its value will be replaced.
- If it does not exist, it will be considered as defining a new variable in the current scope, rather than looking for it in the peripheral scope.
The following functions
def function(): flag = True def helper(): flag = False helper() print flag function()
Since the variable in helper is assignment, the flag output is still True here. Get used to statically typed languages like c languages, this design will be confusing at first, but it can effectively prevent local variables from polluting the environment outside the function.
The requirements are always diverse, and there must be programmers who want to access peripheral scopes when assigning values. If it is Python2, he can do this
def function(): flag = [True] def helper(): flag[0] = False helper() print flag function()
Use flag[0] first to read the variable reference, and find the flag in the peripheral scope. At this time, then assign the value flag[0] = False and the variable will not be newly defined.
If it is Python3, you can use the nonlocal keyword.
def function(): flag = True def helper(): nonlocal flag flag = False helper() print flag function()