为何`if False`代码块中的导入会生成局部变量?
Python中UnboundLocalError的触发原因及文档依据
问题现象
第一段代码可正常运行:
from os import name def function(): # if False: # from os import name print(name) function()
但取消注释if False代码块后,运行会报错:
from os import name def function(): if False: from os import name print(name) function()
报错信息:
UnboundLocalError: cannot access local variable
namewhere it is not associated with a value
原因解析
Python编译函数代码时会做静态作用域分析:扫描整个函数体,只要某个名字是通过赋值语句定义,或是通过from ... import ...引入的,就会把这个名字标记为函数的本地变量——不管对应的代码分支会不会实际执行。
取消注释后,if False里的from os import name让Python把name判定为function的本地变量。当函数执行print(name)时,Python会直接查找本地作用域的name,但这个变量只在永远不会执行的分支里被声明,从未被实际赋值,因此触发UnboundLocalError。
而注释掉那段代码时,函数体内没有name的本地定义,Python会向上查找全局作用域里导入的name,所以能正常运行。
官方文档依据
这个行为是Python的标准规则,在官方文档的「命名和绑定」章节有明确说明:
对于代码块中的名字,如果它出现在赋值语句左侧,或是在import语句中被引入,那么该名字会被视为代码块的本地变量,除非用
global或nonlocal声明修饰。这种判定基于静态代码分析,不考虑代码的执行路径。也就是说,哪怕赋值或import所在的分支永远不会被执行,该名字依然会被标记为本地变量。
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

