全局作用域:全局作用域是指当前代码所在模块的作用域
局部作用域:局部作用域是指当前函数或方法所在的作用域
局部作用域里的代码可以读外部作用域(包括全局作用域)里的变量,但不能更改它。一旦进行更改,就会将其当成是局部变量。而如果在更改前又进行了读取操作,则会抛出异常。
其中,nonlocal是python3.X才引入的
在Python 2.x中,闭包只能读外部函数的变量,而不能改写它。
所以如果要更改外部作用域里的变量,最简单的办法就是将其放入全局作用域,用global关键字引入该变量。
当然这也是py3可以实现的最简单操作。其需要在每个函数中先用global声明,否则会报错
a = 100
def aa():
a += 1
print(a)
aa()
#运算结果如下
Traceback (most recent call last):
File "...", line ..., in
aa()
File "...", line ..., in aa
a += 1
UnboundLocalError: local variable 'a' referenced before assignment
Process finished with exit code 1
只需要加上一行,用global声明一下全局变量a,即可在函数中修改a的值,如下:
a = 100
def aa():
global a
a += 1
print(a)
aa()
print(a)
#运行结果
101
101
Process finished with exit code 0
这里和c语言不同,在开始定义a的时候无需声明为全局变量,而是在函数中说明
那么nonlocal是怎么使用呢
a = 100
def aa():
b = 200
def bb():
b += 2
return b
bb()
aa()
#运行结果
Traceback (most recent call last):
File "...y", line ..., in
aa()
File "...", line ..., in aa
bb()
File "...", line ..., in bb
b += 2
UnboundLocalError: local variable 'b' referenced before assignment
Process finished with exit code 1
b未被赋值,这种情况下我们可以在多层次的函数嵌套中使用nonlocal:
a = 100
def aa():
b = 200
def bb():
nonlocal b
b += 2
return b
print(b)
bb()
print(b)
aa()
#print(b)
#运行结果
200
202
Process finished with exit code 0
注:最后的print(b)依然会报错,因为b是局部变量,仅存在于函数aa()中
而在单层的函数中,nonlocal并不适用:
a = 100
def aa():
nonlocal a
a += 11
return a
print(a)
aa()
print(a)
#运行结果
File "...", line ...
nonlocal a
^
SyntaxError: no binding for nonlocal 'a' found
Process finished with exit code 1
#程序1
def a():
x = 0
def b():
nonlocal x
x += 1
print(x)
return b
#b() 这里有和没有效果一样
a()()
#程序1运行结果
1
Process finished with exit code 0
#程序2
def a():
x = 0
def b():
nonlocal x
x += 1
print(x)
#return b
b() #同样有和没有效果一样
a()()
#程序2运行结果
1
Traceback (most recent call last):
File "...", line ..., in
a()()
TypeError: 'NoneType' object is not callable
Process finished with exit code 1
#程序3
def a():
x = 0
def b():
nonlocal x
x += 1
print(x)
return b #这个有和没有效果一样
#b()
a()
#程序3运行结果
Process finished with exit code 0
#程序4
def a():
x = 0
def b():
nonlocal x
x += 1
print(x)
return b
b()
a()
#程序4运行结果
Process finished with exit code 0
#若将return注释掉,则运行结果
1
Process finished with exit code 0
嵌套两个:
def a():
x = 0
def b():
nonlocal x
x += 1
print(x)
#return b()
b()
def c():
nonlocal x
x += 3
print(x)
#return c()
c()
a()
#运行结果
1
4
Process finished with exit code 0