问题
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 是让底层的 局部作用域 可以访问父级(祖父级)作用域中的 局部变量。




近期评论