问题
num = 10
def changeNum():
num=20
print(num)
changeNum() # 20
print(num) # 10
复制代码
在函数中,直接修改外部变量,修改不生效。
原因:
python
变量访问规则:
由于 python
中变量不需要先定义,赋值即可绑定,所以在 局部作用域
进行对 变量
赋值操作,不会关联到全局作用域(如果要关联,那每定义一个变量,就要在父级,全局查一遍是否存在这个变量,那额外花销太大),而是直接创建一个当前局部作用域
的局部变量
,同时会形成 暂时性死区
(不可在变量声明之前调用) 的现象。
解决
总体思路:通过关键字,将上级或者全局变量映射到当前局部作用域。
global
x=10
# 局部作用域
def changeNum():
# print(x) # SyntaxError: name 'x' is used prior to global declaration
global x
x = 20
a = 'kkk'
def changeStr():
global a
a = 'bbb'
changeStr()
print(a) # kkk
changeNum()
print(x) # 20
print(a) # bbb
复制代码
global
关键字,能将全局作用域
的变量映射到当前作用域,修改后,能生效;- 不可以在
global
字之前使用变量; - 嵌套函数中的变量,不属于全局作用域,所以使用
global
不生效; - 如果全局环境中没有声明的变量,再局部环境使用
global
后,该变量即为全局变量
,在全局依然能访问。
nonlocal
x = 10
# 局部作用域
def changeNum():
# nonlocal x # SyntaxError: no binding for nonlocal 'x' found
x = 20
a = 'kkk'
b = 'ggg'
def changeStr1():
nonlocal a
a = 'bbb'
def changeStr2():
nonlocal b
b = 'ccc'
changeStr2()
changeStr1()
print(a) # bbb
print(b) # ccc
changeNum()
print(x) # 10
复制代码
nonlocal
不可以绑定全局作用域的变量;nonlocal
可以绑定嵌套函数中任何祖先级的局部变量
;
nonlocal
与 global
的区别
最核心一点的是,global
是让 局部作用域
访问全局变量的关键字;nonlocal
是让底层的 局部作用域
可以访问父级(祖父级)作用域中的 局部变量
。