1. LEGB函数
Python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。我们先来看一段代码。
上述代码有两个变量a,当在test函数中输出变量a的值是,为什么输出的是20,而不是10呢?其实是因为变量作用域不同导致的。
变量的作用于决定了在那一部分程序可以访问哪个特定的变量名称。Python的作用于一共有以下四种。L(Local):函数内的区域,包括局部变量和形参。
E(Enclosing):外面嵌套函数区域,常见的是闭包函数外的函数。
G(Global):全局作用域。
B(Bulit-in):内建作用域。
Python中变量采用L->E->G->B的规则查找,即Python检索变量的时候,显示在局部中查找,如果找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,在者去内建中找。
2. 全局变量和局部变量
变量的作用域始终是Python学习中一个必须理解掌握的环节,下面我们从局部变量和全局变量开始全面解析Python中变量的作用域。
所谓局部变量,指的是在定义在函数内的变量。即定义在def函数内的变量名,只能在def函数内使用,它与函数外具有相同的名称的其他变量没有任何关系。不同的函数可以定义相同名字的局部变量,并且各个函数内的变量不会产生影响。
def test1():
num = 100
print("test1中的num值为%d" %num)
def test2():
num = 200
print("test2中的num值为%d" %num)
test1()
test2()
运行结果:
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。全局变量是定义在函数外的变量,它拥有全局作用域。
result = 100#定义一个全局变量,整个代码内调用
def sum(a,b):
result = a + b#定义一个局部变量,在函数内部调用
print("函数内的result的值为:",result)
#函数的返回值,result在这里是局部变量
return result
#调用函数后,打印返回值显示局部变量
sum(100,200)
#直接调用全局变量,跟函数没关系
print("函数外的result是全局变量,等于",result)
运行结果:
3. global和nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
3.1 global关键字
global关键字用来在函数或其他局部作用域中使用全局变量。但是如果不修改全局变量也可以不使用global关键字。
上述程序报错,提示”在赋值前引用了局部变量a“。但是,前面我们明明是可以在函数中访问全局变量的啊。而这里为什么会出错呢?
这就是Python与其他语言不同之处了。在Python中,如果在函数内部对全局变量a进行修改,Python会把变量a当作是局部变量,而在进行”a += 100“之前,我们是没有声明局部变量a的,因此,程序会出现上述错误提示。
为了使全局变量生效,我们可以在函数内使用global关键字进行声明。
这下,程序不但没有报错,而且成功对全局变量进行了修改。
3.2 nonlocal关键字
nonlocal是在Python3.0中新增的关键字。使用nonlocal关键字可以在一个嵌套的函数中修改嵌套作用域中的变量。
上面的程序中,在嵌套的func_in函数中,对变量count赋值,同时会创建一个新的变量,而非使用count = 1语句中的count,如果要修改嵌套作用域中的count,就要使用nonlocal关键字了。
上述代码中,在func_in()函数中使用了nonlocal关键字,就会告诉Python在func函数中使用嵌套作用域中的变量count,因此对变量count进行修改时,会直接影响到嵌套作用域中的count变量,程序最后也就输出12了。
注意:使用global关键字进行修饰的变量之前可以不存在,而使用nonlocal关键字进行修饰的变量在嵌套作用域中必须已经存在。
Python其实没有那么难。