Python变量名解析机制
程序员文章站
2023-12-30 17:09:58
...
Python变量名解析机制
问题描述:
前一段时间在编写python程序定义函数的时候偶尔忘记给函数传入相应参数,结果发现在函数中使用函数外的全局变量竟然不报错而且运行通过了。虽然感觉很奇怪但并没有对这个问题进行解决,今天在阅读《Python学习手册》时找到了这个问题的答案。
先给出一个简单的例子来说明我之前的困惑:
a = 2
def printa():
print(a)
printa()
这个程序按照c等语言的语法来说是会报错的,因为我们没有在printa这个函数内定义变量a,但是在python中程序给出了正确的运行结果‘2’。明明在函数中没有定义a这个变量也没有将a作为参数传入,python为什么实现了对a的输出?
问题解决:
在《Python学习手册》的第418页的 “ 变量名解析:LEGB原则 ” 这一章中给出了答案。
LEGB法则:当在函数中使用未确定的变量名时,Python 搜索 4 个作用域:本地作用域(Loacl),之后是上一层嵌套结构中 def 或 lambda 的本地作用域(Enclosing function locals),之后是全局作用域(Global),最后是内置作用域(Build-in)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错。也就是说python会从本地变量开始自下向上一层一层的查找所用到的变量。
这样我们的问题就很好解释了,当程序运行到print(a)时,python会先在函数内部的本地作用域查找变量a,未找到然后层层向上查找,在全局作用域中找到了这个全局变量a然后完成了对它的输出。
这里还有一点需要注意:当在函数中给一个变量名赋值时,Python会创建或改变本地作用域的变量,而不会对全局的变量进行赋值操作(除非在这个函数中使用global的方式声明该变量为全局变量)。