Python学习中,有时候在命名变量名和访问变量名时总有混乱,于是,我便好好捋一下变量作用域的规则。
1、变量作用域:
标识符的作用域是定义为其声明在程序里的可应用范围, 或者即是我们所说的变量可见性。换句话说,就是你可以在程序里的哪些部分去访问一个变量。变量可以是局部域或者全局域。
命名空间:python的命名空间是对变量名的分组划分。不同组的相同名称的变量视为两个独立的变量,因此隶属于不同分组(即命名空间)的变量名可以重复。所以python的局部变量名称可以和全局变量名称重复。
变量可以在三个地方分配,对应三个不同作用域:
1、 在def内赋值,则是函数之内的局部变量,只在函数内有效。
2、 若变量在嵌套def中赋值,则对于嵌套函数来说,变量不是本地的。
3、 在def之外声明的变量,则是全局变量。
2、变量名解析的LEGB原则:
首先解释LEGB:
L是local,指局部变量,作用于函数内部。
E是Enclosing function locals可能是嵌套函数内,比如python嵌套函数。这个涉及到了函数的闭包,下一篇我再介绍。
G是Global,是全局变量,定义在函数体外,在整个文件中都可以访问。
B是Buildin,Python内置模块的名字空间函数名称等,比如dict、len()等。
Python的命名空间实际是一个字典,字典内保存了变量名称与对象之间的映射关系,因此,查找变量名就是在命名空间字典中查找键-值对。
Python有多个命名空间,因此,需要有规则来规定,按照怎样的顺序来查找命名空间,LEGB就是用来规定命名空间查找顺序的规则。LEGB规定了查找的顺序为:local>enclosing function locals>global>builtin
3、运用实例:
1、LG
变量命名实例:
在函数外面访问函数内的变量:发现变量并没有被定义。
2、LEG查找,请看下面代码以及输出结果
解释一下:上面总共在三个位置都给一个同一个变量名称赋值,但是我们是在最里面的一个函数访问的那个变量,当inner函数要打印a_var变量的时候,它便按照LEGB的顺序查找这个变量,所以便输出了'本地变量'。
3、 Built-in
在python中,我们可以直接查看内置变量,如下;显示一部分
实例:
在这里我们定义了一个自己的len函数,当我们调用len的时候,按照LEGB顺序,是调用我们自己声明的函数,而不是内置函数。
4、global访问修改全局变量
正常情况下我们在函数内访问全局变量,只能对其访问,而不能修改,这时,利用global声明我们就可以修改全局变量。
实例:
注意:不建议在函数内直接修改全局变量,容易造成混乱,因为这经常造成混乱或者很难调试的奇怪错误。如果你想要通过一个函数来修改一个全局变量,建议把它作为一个变量传入,然后重新指定返回值。
码字不易,多多关照,谢谢。