Non-local Python depends on the hierarchy level?

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.

+6
source share
2 answers

global and nonlocal should not be combined. They mean different things:

  • global means the name exists at the module level
  • nonlocal means that the name exists in the outer region of the lexical function

The reason you get the original exception is because you told Python that var is non-local (meaning that it is in the external definition of the function), but it does not bind to the functional level for var in any definition of the external function, because what did you say to Python in the external function that var is global.

+6
source

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 with non-local and vice versa)?

It doesn't matter what level the function is at. This only matters at the level at which the variable is located.

If the functions are at an intermediate and unknown level of the hierarchy, how could the author of the external () change code that neither the external (in this case global) level nor the internal () level should be affected?

You ask if it is possible for a function at an intermediate level to change something in its code to force a variable in an internal function to alternately change something in a global scope or something in an external local function of an external function. It seems really strange that you can to do.

0
source

Source: https://habr.com/ru/post/901020/


All Articles