我把代码改成了这样,让你好理解
- 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"
- print(id(spam))
- do_local()
- print("After local assignment:", id(spam))
- do_nonlocal()
- print("After nonlocal assignment:", id(spam))
- do_global()
- print("After global assignment:", id(spam))
- scope_test()
- print("In global scope:", id(spam))
复制代码
输出结果为
- 2740280630256
- After local assignment: 2740280630256
- After nonlocal assignment: 2740280630128
- After global assignment: 2740280630128
- In global scope: 2740280630000
复制代码
这样就好理解了,第一个spam 赋值是在函数 scope_test下的 是这个函数的局部变量
第一个函数是在自身函数下面建了一个spam局部变量,所以不会被打印
第二个函数是在自身函数下面建了一个可以在scope_test 和 non_local 函数里面使用的局部变量spam
第三个函数是在scope_test外面建立了一个全局变量spam
在do_global 函数执行后,spam并非直接在当前的函数里面创建的spam变量,而是在全局变量中又创建了一个变量
所以这个spam 和 函数中存在的几个spam都不一样
如果,而函数调用属性是这样的,先在函数自身的命名空间找变量名,如果有打印该变量值,然后在上一层命名空间中找如果有变量名,打印变量值,如果没有且在全局变量命名空间,报错
现在你知道do_global为什么返回的为“nonlocal spam”吧,因为在当前的函数命名空间下,已经有了一个叫spam的nonlocal变量名,就不会再去上一层空间找了