简体   繁体   中英

running python doc example has don't understand something in python scope and namespace chapter?

I learning python3.6 document, and when I look at python scopes and namespaces , I'm try running this code, i found in scope_test() call do_local() print result is different with me thought :

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)

I think when call do_local() should be find spam in do_local() scope, because of do_local() scope has spam variable, so:

do_local()
print('After local assignment:', spam) # local spam

unless do_local() not has spam variable, and then can find spam in scope_test()

but python Interpreter print result is:

do_local()
print('After local assignment:', spam) # test spam

do_local

is similarly with when call do_global() , I think in this scope, bacause global spam is global, so:

do_global()
print("After global assignment:", spam) # test spam

but why result is:

do_global()
print("After global assignment:", spam) # nonlocal spam
def scope_test():
    def do_local():
        spam = "local spam" #this spam variable is in do_local's scope
    def do_nonlocal():
        nonlocal spam #this spam variable refers to spam variable defined in outer function's ,that is scope_test's,scope
        spam = "nonlocal spam"
    def do_global():
        global spam #this refers spam variable defined outside all functions (global)
        spam = "global spam"

    spam = "test spam" #this spam variable is defined in scope_test's scope

    do_local()
    print("After local assignment:", spam) #this spam var is still in scope_test's scope

    do_nonlocal() #do_nonlocal is called and inside that spam variable (defined nonlocal) is changed which changes scope_test's spam
    print("After nonlocal assignment:", spam) #this print is also in scop_test's scope but above function changed current scope's value 

    do_global() #changes spam var in global scope 
    print("After global assignment:", spam) #prints spam var in scop_test

scope_test() #execution starts
print("In global scope:", spam) #prints spam var in global scope as this print statement is in global scope

Here is the result I got after running your program. Let's go through it.

def do_local():
    spam = "local spam"

An object spam is created which only has a scope limited to this function do_local and it get's destroyed as soon as the life of function ends. Hence, after local assignment, you see the output of test spam, which was defined using spam = "test spam" which has a scope pertaining to function scope_test.

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

By using the nonlocal keyword you're telling the interpreter that you're working with an object that is not limited to the scope of function do_nonlocal . Hence, the interpreter searches for this object outside this function's scope and it finds it in the function scope_test . It then assigns the value of "nonlocal spam" to this spam object pertaining to the scope of function scope_test .

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

Here you're actually creating a global object spam and assigning it the value of "global spam". Remember: This is global to the scope of your whole program. But when you print out spam, python looks for spam object and finds it in your function's scope only, ie spam which was allocated a value of "nonlocal spam" in do_nonlocal function call, hence you see nonlocal spam as your output.

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

After running scope test, the spam object's scope which contained the value of "test spam" initially, persists to exist after function scope_test is over. Hence when you try to print out spam again, the global object spam gets printed out which you created when you called out do_global while in you were in test_scope .


I hope it clears out some confusion from your mind!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM