This question is a continuation of the Python variable domain question . Additional questions q1 , q2 and answers can be found on SO, among even more. The official Python and PEP 3104 Documentation to explain the details, but they don't seem completely clear to me.
The topic I'm trying to solve is refactoring code that contains nonlocal / global by moving this code up / down one level in the hierarchy.
What I don't understand are the consequences of this sentence from a Python link:
The names listed in the non-local statement, unlike those listed in the global operator, must refer to previously existing bindings in the closing scope (the area in which you want to create a new binding cannot be uniquely defined).
Given the following code in a global scope:
var = 0 def outer(): global var # line A var = 1 def inner(): nonlocal var # line B var = 2 print('inner:', var) inner() print('outer:', var) outer() print('main:', var)
Execution causes an error:
SyntaxError: no binding for nonlocal 'var' found
The code works (with different semantics, of course, if any line A is commented out:
inner: 2 outer: 2 main: 0
or line B is commented out:
inner: 2 outer: 1 main: 1
However, in the above example, and since nonlocal supposed to associate var with the "scope", I would expect line A to connect the external / var to the global area and line B, then look for the external / var, and also restore the internal / var to global / var. Instead, he does not seem to find it at all (due to the ligation in line A, I suppose) and throws an error.
The desired result that I expected was:
inner: 2 outer: 2 main: 2
Is this another example of a confused state of consciousness in Python?
Or, to make this constructive question:
- How can such an example be written in such a way that it does not matter at what level the function is located (it is necessary to exchange
global for nonlocal and vice versa)? - If functions are at an intermediate and unknown level in the hierarchy, how can the author of
outer() change code that should not affect the most external (in this case global) level, nor the inner() level? -
In my humble understanding of a language, constructs like these (closure dependencies) should be avoided. Others have already suggested using other language functions ( classes , func attrs ) to achieve this contextual sensitivity.