Search code examples
pythonscoping

Why doesn't `global` statement affect blocks inside current block?


def foo():
    global a
    def bar():
        nonlocal a
        a = 6
    bar()

a = 5
foo()
print(a)

Trying to run a module consisting of code listed above results in SyntaxError: no binding for nonlocal 'a' found. But I expected that it would run and print 6, why doesn't it?

Notice, that if we replace the global a statement with a statement that binds the name a (e.g. from something import otherthing as a or a = 0), then there's no SyntaxError, and the print(a) statement outputs 5 as expected.

I read https://docs.python.org/3/reference/executionmodel.html#naming-and-binding but didn't understand what global and nonlocal statements do.


Solution

  • a is bound in the top level namespace.

    The nonlocal statement causes corresponding names to refer to previously bound variables in the nearest enclosing function scope.

    But a is not bound in a function scope so

    SyntaxError is raised at compile time

    In other words global does not affect where a is bound.