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
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
.
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.