关于Python LEGB查找规则的疑问:赋值语句为何触发UnboundLocalError?
关于Python LEGB规则与UnboundLocalError的解惑
你的核心误解在于Python的变量绑定时机,而非LEGB查找规则本身。
首先明确LEGB规则的正确逻辑:Python解释器查找变量时,确实会按「局部(Local)→嵌套(Enclosing)→全局(Global)→内置(Builtin)」的顺序查找,但这个规则的生效有个前提——变量在当前作用域中没有被标记为「局部绑定」。
为什么第一个例子正常?
x = 10 def myfunc(): print(x)
函数myfunc内部没有对x的赋值操作,Python解析时不会把x标记为局部变量。执行print(x)时,局部作用域找不到x,就会按LEGB规则向上找到全局作用域的x=10,所以输出正常。
为什么第二个例子报错?
x = 10 def myfunc(): x = x * 2 print(x)
Python在编译函数代码阶段,只要发现函数内部存在对x的赋值语句(x = ...),就会直接把x标记为该函数的局部变量。当函数执行到x * 2时,Python会优先在局部作用域查找x,但此时局部的x还未被赋值,因此抛出UnboundLocalError——它根本不会去全局作用域查找x。
解决方法
如果想要修改全局变量x,需要用global关键字声明该变量属于全局作用域:
x = 10 def myfunc(): global x x = x * 2 print(x)
global告诉Python:这个x是全局作用域的变量,右侧的x会按LEGB找到全局的x=10,计算后重新赋值给全局的x,调用后输出20。
如果想要创建局部变量x并使用全局x的值,可以先将全局x的值赋值给局部变量:
x = 10 def myfunc(): x = globals()['x'] * 2 print(x)
或者先显式获取全局值再操作:
x = 10 def myfunc(): local_x = x local_x *= 2 print(local_x)
内容的提问来源于stack exchange,提问作者Sabbir Ahmed
相关产品推荐
相关产品推荐

