Python学习中,有时候在命名变量名和访问变量名时总有混乱,于是,我便好好捋一下变量作用域的规则。

1、变量作用域:

标识符的作用域是定义为其声明在程序里的可应用范围, 或者即是我们所说的变量可见性。换句话说,就是你可以在程序里的哪些部分去访问一个变量。变量可以是局部域或者全局域。

python if 影响作用域 python作用域规则_命名空间

命名空间:python的命名空间是对变量名的分组划分。不同组的相同名称的变量视为两个独立的变量,因此隶属于不同分组(即命名空间)的变量名可以重复。所以python的局部变量名称可以和全局变量名称重复。

python if 影响作用域 python作用域规则_命名空间_02

变量可以在三个地方分配,对应三个不同作用域:

1、 在def内赋值,则是函数之内的局部变量,只在函数内有效。

2、 若变量在嵌套def中赋值,则对于嵌套函数来说,变量不是本地的。

3、 在def之外声明的变量,则是全局变量。

python if 影响作用域 python作用域规则_python if 影响作用域_03

2、变量名解析的LEGB原则:

首先解释LEGB:

L是local,指局部变量,作用于函数内部。

E是Enclosing function locals可能是嵌套函数内,比如python嵌套函数。这个涉及到了函数的闭包,下一篇我再介绍。

G是Global,是全局变量,定义在函数体外,在整个文件中都可以访问。

B是Buildin,Python内置模块的名字空间函数名称等,比如dict、len()等。

Python的命名空间实际是一个字典,字典内保存了变量名称与对象之间的映射关系,因此,查找变量名就是在命名空间字典中查找键-值对。

python if 影响作用域 python作用域规则_python if 影响作用域_04

Python有多个命名空间,因此,需要有规则来规定,按照怎样的顺序来查找命名空间,LEGB就是用来规定命名空间查找顺序的规则。LEGB规定了查找的顺序为:local>enclosing function locals>global>builtin

3、运用实例:

1、LG

变量命名实例:

python if 影响作用域 python作用域规则_python作用域的顺序_05

在函数外面访问函数内的变量:发现变量并没有被定义。

python if 影响作用域 python作用域规则_python if 影响作用域_06

2、LEG查找,请看下面代码以及输出结果

python if 影响作用域 python作用域规则_变量名_07

解释一下:上面总共在三个位置都给一个同一个变量名称赋值,但是我们是在最里面的一个函数访问的那个变量,当inner函数要打印a_var变量的时候,它便按照LEGB的顺序查找这个变量,所以便输出了'本地变量'。

3、 Built-in

在python中,我们可以直接查看内置变量,如下;显示一部分

python if 影响作用域 python作用域规则_变量名_08

实例:

python if 影响作用域 python作用域规则_python if 影响作用域_09

在这里我们定义了一个自己的len函数,当我们调用len的时候,按照LEGB顺序,是调用我们自己声明的函数,而不是内置函数。

4、global访问修改全局变量

正常情况下我们在函数内访问全局变量,只能对其访问,而不能修改,这时,利用global声明我们就可以修改全局变量。

实例:

python if 影响作用域 python作用域规则_python if 影响作用域_10

注意:不建议在函数内直接修改全局变量,容易造成混乱,因为这经常造成混乱或者很难调试的奇怪错误。如果你想要通过一个函数来修改一个全局变量,建议把它作为一个变量传入,然后重新指定返回值。

python if 影响作用域 python作用域规则_命名空间_11

码字不易,多多关照,谢谢。

python if 影响作用域 python作用域规则_变量名_12