global

转载自:https://blog.csdn.net/qw_sunny/article/details/80972357 

python变量引用顺序:从当前作用域开始寻找变量,如果没找到就往上一层作用域寻找,没找到就再上一层......

即:当前作用域局部变量->外层作用域变量->再外层作用域变量->......->当前模块全局变量->pyhton内置变量

global:全局变量

nonlocal:外层嵌套函数的变量

使用总结:

1、局部作用域改变全局变量用global, global同时还可以定义新的全局变量

2、内层函数改变外层函数变量用nonlocal, nonlocal不能定义新的外层函数变量,只能改变已有的外层函数变量

     同时nonlocal不能改变全局变量

 nonlocal关键字

# 1.外部必须有这个变量
# 2.在内部函数声明nonlocal变量之前不能再出现同名变量
# 3.内部修改的这个变量 直到在外部有这个变量的一层函数中 生效

一global总结
1、没有关键字(a1、a2、a3分别是不同变量)

 1 a = 10  # a1 当前模块全局变量
 2 def outer():
 3     a = 9  # a2 当前outter作用域局部变量
 4     def inner():
 5         a = 8  # a3 当前inner作用域局部变量
 6         print(a)  # a3 8, 在inner的局部作用域中找到了a3
 7     inner()  # inner()函数结束,a3作为inner局部变量被释放
 8     print(a)  # a2 9,在outer局部作用域中找到a2
 9 outer()  # outer()函数结束,a2作为outer局部变量被释放
10 print(a)  # a1 10, 在当前模块全局作用域中找到了a1

2、在局部作用域中修改全局变量(a1、a3是同一个变量,都是全局变量a)

 1 a = 10  # a1 当前模块全局变量
 2 def outer():
 3     a = 9  # a2 当前outter作用域局部变量
 4     def inner():
 5         global a
 6         a = 8  # a3 既是全局变量a1,又是inner局部变量
 7         print(a)  # a3 8,在inner的局部作用域中找到了a3
 8     inner()  # inner()函数结束,a3作为全局变量被保留下来成为a1
 9     print(a)  # a2 9,在outer局部作用域中找到a2
10 outer()  # outer()函数结束,a2作为outer局部变量被释放
11 print(a)  # a1 8, 在当前模块全局作用域中找到了a1

3、若没有在外部定义全局变量a,在局部作用域中加global关键字依然能声明一个变量为全局变量

 1 def outer():
 2     a = 9  # a2 当前outter作用域局部变量
 3     def inner():
 4         global a
 5         a = 8  # a3  既是inner局部变量,又是模块全局变量
 6         print(a)  # a3 8 在inner的局部作用域中找到了a3
 7     inner()  # inner()函数结束,a3作为全局变量被保留下来
 8     print(a)  # a2 9,在outer局部作用域中找到a2
 9 outer()  # outer()函数结束,a2作为outer局部变量被释放
10 print(a)  # a3 8在当前模块全局作用域中找到了a3

4、outer()没有局部变量a,则往上使用全局变量a

1 def outer():
2     def inner():
3         global a
4         a = 8  # a3  既是inner局部变量,又是模块全局变量
5         print(a)  # a3 8,在inner的局部作用域中找到了a3
6     inner()  # inner()函数结束,a3作为inner局部变量被释放
7     print(a)  # a3 8,在outer局部作用域中没找到a,往上在全局作用域中找到了全局变量a3
8 outer()  # outer()函数结束,a2作为outer局部变量被释放
9 print(a)  # a3 8,在当前模块全局作用域中找到了a3

二、nonlocal关键字:声明此变量与外层同名变量为相同变量

1、用于在内层函数中改变外层函数变量(a2、a3为同一变量)

 1 a = 10  # a1 当前模块全局变量
 2 def outer():
 3     a = 9 # a2 outer局部变量
 4     def inner():
 5         nonlocal a
 6         a = 8  # a3  既是inner局部变量,又是外层outer局部变量
 7         print(a)  # a3 8,在inner的局部作用域中找到了a3
 8     inner()  # inner()函数结束,a3作为外层变量(outer局部变量)被保留成为a2
 9     print(a)  # a2 8,在outer局部作用域中找到a2(在inner中被改变)
10 outer()  # outer()函数结束,a2作为outer局部变量被释放
11 print(a)  # a1 10,在当前模块全局作用域中找到了a1

2:如果在外层没有找到变量a,则会继续在再外层寻找,直到全局作用域的下一层为止

 1 a = 10  # a1 当前模块全局变量
 2 def outer2():
 3     a = 9 # a2 outer2作用域局部变量
 4     print(a) # a2 9,还未被a3改变
 5     def outer1():
 6         print(a) # a2 9,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(还未被a3改变)
 7         def inner():
 8             nonlocal a
 9             a = 0  # a3 既是inner局部变量,又是再外层outer2作用域变量
10             print(a)  # a3 0, 找到inner局部变量a3
11         inner()  # inner()函数结束,a3作为外层变量(outer2局部变量)被保留成为a2
12         print(a)  # a2 0,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(被a3改变)
13     outer1()
14     print(a) # a2 0, 在outer1中找到outer1局部变量a2(被a3改变)
15 outer2() 
16 print(a)  # a1 10,在当前模块全局作用域中找到了a1

3、全局变量不是外层变量,不能被nonlocal寻找,否则会报错

a = 10  # a1 当前模块全局变量
def outer():
    def inner():
        nonlocal a  # 在当前作用域外层即outer局部作用域中没找到outer局部变量a,outer外层为全局作用域,nonlocal不继续寻找,报错
        a = 8
        print(a)
    inner()
    print(a)
outer() 
print(a)  # a1 10,在当前模块全局作用域中找到了a1

 

报错如下:

nonlocal a # 在当前作用域外层即outer局部作用域中没找到outer局部变量a,outer外层为全局作用域,nonlocal不继续寻找,报错
^
SyntaxError: no binding for nonlocal 'a' found

 

posted on 2019-01-22 11:11  jak06  阅读(286)  评论(0编辑  收藏  举报