Python解释器如何识别函数内部未定义的全局变量?
def show(): print(a) a = 1 show()
运行逻辑原理解析
- 核心规则:Python 对函数内的变量采用延迟绑定机制,函数定义阶段和执行阶段的处理逻辑完全分开。
函数定义阶段,解释器只会做两件事:
- 校验函数体的语法是否合法,只要没有语法错误就不会抛出异常
- 把函数体代码编译为字节码暂存,不会实际执行内部语句,也不会立刻解析变量对应的实际内存对象
- 变量的实际查找逻辑,是在函数被调用执行的时候才触发的,遵循LEGB查找规则:
优先从当前函数局部作用域找变量→找不到就去外层闭包作用域找→再找不到就去全局作用域找→最后去内置作用域找,所有层级都找不到才会抛出NameError。
对应你的代码逐阶段解释:
- 执行到
def show():行时,仅完成函数注册,print(a)里的a被识别为变量名,对应字节码会记录要查找名为a的对象,但不会触发实际查找 - 接下来执行
a = 1,全局作用域成功创建变量a,赋值为1 - 最后调用
show()时才会执行函数体内的字节码,触发a的查找逻辑:局部作用域没有a,就去全局作用域找,顺利拿到值1,所以可以正常输出。
是否在函数被调用前,变量仅被视为普通字符处理?
不是的,函数定义阶段已经把a识别为待查找的变量名,不是普通字符。你可以测试把a = 1放到show()调用之后,运行就会直接抛出NameError,说明变量名的识别是提前完成的,只是绑定实际值的时机延迟到了执行阶段。
至于你说的字节码看不懂的问题,可以找代码对应生成的LOAD_NAME或者LOAD_GLOBAL指令,这个指令就是标记执行到此处需要查找对应名称的变量,定义阶段这个指令只是作为操作码存下来,不会实际执行查找动作。
内容的提问来源于stack exchange,提问作者D H
相关产品推荐
相关产品推荐

