为何Python函数中try-except块后无法访问全局变量x?
问题描述
运行以下代码时完全正常:
x = 1 def func(): print(x + 1) func()
输出:
2
但运行这段代码时出现错误:
x = 1 def func(): try: x += 1 except: pass print(x + 1) func()
错误信息:
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
疑问:已经用try-except规避修改全局变量的异常,原以为捕获异常后print(x + 1)会像第一段代码一样读取全局x,但实际报错,到底是try-except的作用域变化导致的吗?
原因解析
核心问题和try-except的作用域无关,而是Python的作用域判定规则导致的:
- Python在解析函数定义时,会扫描整个函数体的代码,如果发现有对变量的赋值操作(哪怕是在分支、异常块里),就会把这个变量标记为该函数的局部变量,而不会再去全局作用域查找这个变量。
- 第一段代码里,函数
func只是读取x的值,没有任何赋值操作,所以Python会先查找局部作用域的x,找不到就去全局作用域拿x=1,因此能正常输出2。 - 第二段代码里,
x += 1本质是x = x + 1,包含了赋值操作,所以Python在解析func时就把x标记为局部变量。虽然try块的异常被捕获了,但局部变量x从未被赋值(绑定任何值),后面执行print(x + 1)时,Python尝试访问这个未绑定的局部变量,就抛出了UnboundLocalError。
简单说:哪怕赋值操作在永远不会执行的代码块里,Python也会把变量标记为局部的,后续访问都会优先找这个未绑定的局部变量,而不是全局变量。
内容的提问来源于stack exchange,提问作者UpTheIrons
相关产品推荐
相关产品推荐

