Reputation: 31
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
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