Python函数中变量赋值如何检测?为何死代码内赋值仍触发UnboundLocalError
核心原因:Python编译阶段的执行顺序决定了这个结果
Python把代码转成可执行的字节码要经过两个关键步骤,顺序是固定的:先做语法解析和变量作用域判定,再做字节码优化,两个步骤的结果互不干扰。
- 第一步:作用域判定(优化前执行)
编译阶段第一步会扫描整个函数的完整语法树,检查所有变量的赋值行为:
只要函数内任意位置存在对变量的赋值操作,且没有显式声明
global/nonlocal,就会直接将该变量标记为局部变量,后续对该变量的引用都会生成指向局部变量槽的LOAD_FAST指令,你反汇编结果里的LOAD_FAST 0 (a)就是这一步的产物——如果a被判定为全局变量,这里应该是LOAD_GLOBAL指令。
这个判定不会管赋值语句所在的代码块会不会被实际执行,只要语法上存在赋值语句就会生效。
- 第二步:死代码优化(作用域判定后执行)
作用域判定完成后,Python的窥孔优化器会清理确定不会执行的死代码,你写的if False:块属于100%不会执行的静态死代码,所以里面的a=2对应的STORE_FAST指令会被直接删掉,最终生成的字节码里就看不到这部分操作。
报错原因
字节码执行到LOAD_FAST 0 (a)时,会直接去函数的局部变量槽里取索引为0的变量,但因为STORE_FAST被优化掉了,这个槽位从来没被赋值过,就触发了UnboundLocalError。
内容的提问来源于stack exchange,提问作者filaton
相关产品推荐
相关产品推荐

