binding of nonlocal for specific function

51 Views Asked by At
x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        def vnat():
            nonlocal x
            x = 5
            print('vnat:', x)

        vnat()
            
        print('inner:', x)

    
    inner()
    print('outer:', x)


outer()
print('global:', x)

Here is the result:

vnat: 5
inner: 5
outer: 5
global: 0

Why is def outer() taking the value of def vnat() (5)? And how can I specify def outer() with value of nonlocal x from def inner() [2]?

Output I need:

vnat: 5
inner: 5
outer: 2
global: 0
1

There are 1 best solutions below

0
On BEST ANSWER

Whenever you specify nonlocal x it will refer to the name of an enclosing scope. So in your example, you have the following nesting of scopes:

global --> outer --> inner --> vnat
  |         |          |        |
  v         v          v        v
 x=0       x=1  <--nl--x <--nl--x       "nl" stands for "nonlocal"

So vnat refers to its enclosing scope's x (which is the scope of inner) which in turn refers to its enclosing scope's x (which is the scope of outer). For that reason, if you assign to x in vnat it will effectively assign to outer's name x.