python global 与 nonlocal
global 关键字
定义在main函数或者外部的变量是全局变量,我们可以访问,但是如果需要求改则需要使用改关键词.
即如果需要在局部域修改全局变量,则需要需要使用global关键字再次声明
def scope():
global a, t # 否则不能修改
a += 1
t += 'yy'
print(a, t, g)
if __name__ == '__main__':
a = 0
t = 'sss'
g = [1, 2, 3]
scope()
1 sssyy [1, 2, 3]
否则如下则修改失败
a = 'init...'
def scope():
a = 'change..'
if __name__ == '__main__':
scope()
print(a)
init...
nonlocal 关键字
简单说,该关键字用在嵌套函数中,可以用来改变一个变量的作用域,即在本不是该局部域的变量作用域的地方,继续使用该变量
如下,如果没有使用nonlocal 关键字,因为msg 是不可变类型,所以msg由原来的outisde变成inside,值变了,python就会重新开辟新内存,导致不能修改“原来的值outside”
def outside():
msg = "Outside!"
def inside():
nonlocal msg # 若去掉, 则修改不会成功。结果输出“outside!”
msg = "Inside!"
inside()
print(msg)
outside()
Inside!
但是该变量不能作用于全局变量。因为也好理解,如果你要修改,则可以用global
如下,会报错:
msg = "Outside!"
def outside():
def inside():
nonlocal msg
msg = "Inside!"
inside()
print(msg)
outside()
nonlocal msg
^
SyntaxError: no binding for nonlocal 'msg' found
补充例子:
如下,对于可变类型,在外层函数id(d)和内层函数id(d)是一致的,而修改的是d["outside"]会导致内存改变——d['outside']是不可变类型,如下使用id(d['outside'])查看确实改变了,但是对于整体的id(d)是不变的,所以不需要使用nonlocal也可以修改成功
def outside():
d = {"outside": 'init'}
print(id(d))
print(id(d['outside']))
def inside():
d["outside"] = 'change'
print(id(d)) # 是一致的, 没有改变
print(id(d['outside'])) # 改变了,但是只要id(d)未改变就能修改成功
inside()
print(d)
outside()
{'outside': 'change'}
============
当我沉默时,我觉得充实。当我开口说话时,却觉得空虚
===========