back

by ripe·4y ago·view on hn ↗
Thank you for writing the post. Newbie question about “nonlocal” from your example:

    def outer_function():
        x = 11

        def inner_function():
            nonlocal x
            x = 22
            print('Inner x:', x)

        inner_funcion()
        print('Outer x:', x)
I get how the example works, but don’t see the point of the declaration? If I just left out the “nonlocal x” line, wouldn’t the example still work the same?
1 comments
Python assumes that all assignments assign to the current scope. So by default when you reach "x = 22", it would create a new variable called "x" in the inner_function() scope which overrides the variable "x" in the outer_function() scope. So when you print "Inner x" you would only be printing the inner_function() version of x, not the outer_function() version, which would remain at 11.
This is a consequence of python not having explicit variable definition. Here it'll decide to define a new x instead of seeing the old one.

And that's also usually what you want because otherwise a function would start altering variables in the enclosing scope if they happen to exist!

E.g.

    foo = 42

    def myfunc(bar):
        foo = bar + 1
        print(foo)
    myfunc(6)
    print(foo) # would print "7" if the "foo =" above took the nonlocal foo automatically!
So the trade-off is to require "nonlocal" if you ever need a variable from the enclosing scope.