programming is fun123
programming is fun123

Reputation: 31

Confusion about the nonlocal and global names in python

So i've been reading a little in the python toturial and I stumbled upon something that I don't quite understand.

When i write the following code into the interpreter:

    >>> def scope_test():
    ...    def try_add():
    ...       nonlocal spam
    ...       spam = "new spam"
    ...    try:
    ...       print(spam)
    ...    except:
    ...       print("exception caught")
    ...    try_add()
    ...    print(spam)

I get the following error:

      File "<stdin>", line 3
    SyntaxError: no binding for nonlocal 'spam' found

but when I run this code:

>>> def scope_test():
...    def try_add():
...       global spam
...       spam = "new spam"
...    try:
...       print(spam)
...    except:
...       print("exception caught")
...    try_add()
...
>>> scope_test()
exception caught
>>> spam
'new spam'

It runs fine.

What is the explanation to this?

Upvotes: 0

Views: 705

Answers (1)

wtw
wtw

Reputation: 688

From the documentation: https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement

Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).

(emphasis mine). The statement after the emphasis tells you why this should be so.

With global if the variable does not exist then it can be made in the global scope. So, in your example with global python happily creates spam in the global scope.

With nonlocal, if the variable does not exist, in which scope should it be created? There could be many scopes between the nearest enclosing scope and global. Rather than guess, nonlocal insists that the variable already exists. In your example using nonlocal, there isn't a spam anywhere between the enclosing scope and the global scope, so you get the error.

Upvotes: 1

Related Questions