snapper
snapper

Reputation: 1187

Regarding Scope : Global and Local Assignment

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)

Hi I am dealing with python class and faced with above example from the official documentation.

Output:

After local assignment: test spam

After nonlocal assignment: nonlocal spam

After global assignment: nonlocal spam

In global scope: global spam

The result of the first print after do_local still prints "test spam" but can't figure out why while the second print gives "nonlocal spam".

What makes the difference?

My inference is, if I do_local() then it runs the do_local() and it changes the spam variable as "local spam" and it might have to work same with do_nonlocal() which results in "nonlocal spam". But it's not.

Why?

Upvotes: 2

Views: 256

Answers (1)

Alperen
Alperen

Reputation: 4602

Here is a global variable example(from here):

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

As you can see in this example, global means the variable which is available in any place in the script. If you define or change a global variable in a function, you can use it in another function with global keyword.

Even you can delete this first definiton line in the example:

globvar = 0

It works anyway as global variable. So, when you use global keyword it is available in any scope in the script.

nonlocal definition from here

Python 3 introduced the nonlocal keyword that allows you to assign to variables in an outer, but non-global, scope.

It means, when you use nonlocal keyword it is available outer scope. In this situation, "nonlocal spam" in do_nonlocal() function is available in scope_test() function too, but not one more outer scope.

If you don't use global and nonlocal keyword, then define "spam" in a function, it is just a local variable which is deleted when the function is over.

EDIT

This is not the same code, but prints the same result. For a better understanding, the situation is something like this:

spam_1 = ""

def scope_test():
    def do_local():
        spam_3 = "local spam"

    def do_nonlocal():
        nonlocal spam_2
        spam_2 = "nonlocal spam"

    def do_global():
        global spam_1
        spam_1 = "global spam"

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

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

Upvotes: 2

Related Questions