Python 入门 10 —— 变量的作用域:global、nonlocal

一般地,将在函数外定义的变量称为:外部变量(全局变量);在函数内定义的变量称为:内部变量(局部变量)。

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

———————————————— 本篇完 ————————————————

看完之后,麻烦您顺手点击下方 “点赞” 两个字给我点个赞吧 ^-^ , 谢谢您了。

如果您还能像我小学一年级班主任好老师那样,给我随心写上几句表扬或批评的话语,那真是感激不尽!

在我人生的道路上,有了您的鼓励和指导,我一定成长快快。

发布了28 篇原创文章 · 获赞 6 · 访问量 2279

猜你喜欢

转载自blog.csdn.net/Jeff888999/article/details/103945641