一般地,将在函数外定义的变量称为:外部变量(全局变量);在函数内定义的变量称为:内部变量(局部变量)。
global 用法普遍;nonlocal 仅在内嵌函数中使用。
一、关键词 global
1、内部变量仅可在函数内使用,函数结束时自行销毁,在函数外无法访问。例如:
def fun(x,y): z = 18; print(x,y,z) # 内部变量 z
fun(11,12) # 11 12 18
print(z) # z 是内部变量,在函数外不能访问:NameError: name 'x' is not defined
2、如果要使内部变量变成全局变量,以便在函数外使用,必须用关键词 “global” 声明一下。这里要注意的是,声明语句必须是单独成句,不能把声明与赋值放在同一句中,否则会报错。例如:
def fun(x,y): global z; z= 18; print(x,y,z)
fun(11,12) # 11 12 18
print(z) # z 在用“global” 声明之后成了全局变量:18
3、外部变量在函数内可以访问,但不可以修改。如果要修改,必须用“global”声明一下。如果一个内部变量与外部变量同名,则在函数内,外部变量会被暂时隐藏(屏蔽)
a= 16
def fun(x,y,z): print(x,y,z,a) # a 是外部变量,在函数内可以访问
fun(11,12,13) # 11 12 13 16
a= 16
def fun(x,y,z): global a; a= 18; print(x,y,z,a)
fun(11,12,13) # 11 12 13 18
print(a) # 外部变量a 在函数内被修改:18
a= 16
def fun(x,y,z): a= 18; print(x,y,z,a) # a 是外部变量,可以访问
fun(11,12,13) # 11 12 13 18
print(a) # 外部变量a 在函数内只是被暂时隐藏,没有被修改:16
二、nonlocal
nonlocal 的问题是函数嵌套引起的。如果没有函数嵌套,将所有变量分为外部变量(全局变量)和内部变量(局部变量)就够了。有了函数嵌套,问题就变得复杂了。例如:
def fun01(x):
a = 11
def fun02(y):print(y,a)
fun02(x)
fun01(10) # 10 11
print(a) # NameError: name 'a' is not defined
在 fun01() 内部又定义了一个函数fun02()。在fun01()看来,变量 a 肯定是内部变量。但在fun02()看来,a 不是内部变量,也不是全局变量,称之为“中间变量”比较合适。按照上述第一部分的规则:在fun02()中引用a,是可以的,但要修改 a 就要加上 global 声明。例如:
def fun01(x):
a = 11
def fun02(y):global a; a =12; print(y,a)
fun02(x)
fun01(10) # 10 12
print(a) # 变量 a 这时成了全局变量:12
问题是,如果在fun02()中想修改 a,但又不想使它成为全局变量,以确保 a 在 fun01() 结束后自动销毁,该如何办呢?答案是:使用 nonlocal 关键词声明 a 。
def fun01(x):
a = 11
def fun02(y):nonlocal a; a =12; print(y,a)
fun02(x)
fun01(10) # 10 12
print(a) # a 在 fun01() 结束后被自动销毁:NameError: name 'a' is not defined
由上可见,nonlocal关键词仅在内嵌函数内使用。它用于声明:被声明的变量是引用自上一层的函数。对比 global 用于声明:被声明的变量是引用自自全局变量,二者的用法是很有相似之处的。
global 还可以在函数内用于声明一个新的变量为全局变量,那 nonlocal 是否可以在内嵌函数内用于声明一个新的变量为“仅可以在上一层函数使用的变量”呢?不可以。用 nonlocal 声明的变量如果在上一层的函数中不存在,则会报错。例如:
def fun01(x):
a = 11
def fun02(y):nonlocal a; nonlocal b; a =12; print(y,a,b)
fun02(x)
# 因为变量 b 在fun01()中没有被定义,所以会报语法错误: 在SyntaxError: no binding for nonlocal 'b' found
———————————————— 本篇完 ————————————————
看完之后,麻烦您顺手点击下方 “点赞” 两个字给我点个赞吧 ^-^ , 谢谢您了。
如果您还能像我小学一年级班主任好老师那样,给我随心写上几句表扬或批评的话语,那真是感激不尽!
在我人生的道路上,有了您的鼓励和指导,我一定成长快快。