-3

While going through Python Scope documents, I came across the following code, but I am not sure how execution of this code works. Can someone explain this 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)
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
AutomationNerd
  • 406
  • 1
  • 5
  • 12

1 Answers1

0

Easiest way to find out - Run the program! This is the output:

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

As you can see, nonlocal takes priority inside the defined scope. Once out, the global definition is used. No need to reset the global value, this is done automatically. nonlocal overwrites local assignment, of course.

Edit: See this related question for more information.

Tgilgul
  • 1,614
  • 1
  • 20
  • 35
  • Still don't understand why this is the case. Can you explain more why this is the output step by step? Why we call do_local(), why spam is not changed? When we call do_global(), why inside the scope_test, it is still nonlocal, but actually spam becomes global spam? – ycenycute Feb 06 '18 at 17:15
  • From Python documentation: "The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals". In this case the "nearest enclosing scope" is the scope_test() function. So anywhere within this function we will get the nonlocal value, even after setting the global value. the last call is from the global scope, so the value is the global value. The first call is to do_local(), before we set the field to be nonlocal, so we get the local value. If you'll try to call do_local() again in the end you'll get the nonlocal value. – Tgilgul Feb 07 '18 at 14:52