2

I've been following the tutorial in the Python docs and I came across the code about the use of the global and nonlocal keywords. I've read through the code but I don't quite understand why some of the code does what it does. Here's the code:

def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

Printout:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

After the do_global() call, why does spam print out nonlocal spam? Shouldn't it be printing out global spam?

Thanks!

Andrew
  • 3,501
  • 8
  • 35
  • 54
  • possible duplicate of [How are functions inside functions called? And can I access those functions or they work like "helper methods"?](http://stackoverflow.com/questions/16358375/how-are-functions-inside-functions-called-and-can-i-access-those-functions-or-t) – Shawn Mehan Aug 08 '15 at 20:09
  • @ShawnMehan Although both questions use the same code sample, the earlier question does not ask about the printouts. – Paul Aug 10 '15 at 05:09

1 Answers1

1

The do_global call assigns a global variable (one defined in a scope outside of all functions). The print function inside the scope_test function is still referring to the spam inside the local scope of that function.

Therefore, since the global keyword makes the value "global spam" assigned to the global scope of spam, the change is not applied to the local scope, and the unchanged local scope is still printed.

The specific mechanism for checking this by Python is by searching for a variable in he most local scope, finally ending in the global scope. This is why local variables are always referenced before globals of the same name.

bcdan
  • 1,438
  • 1
  • 12
  • 25