为何使用+=运算符会触发Python的UnboundLocalError?
为什么列表使用
+=运算符在函数内会触发UnboundLocalError,而append方法却正常? 先看触发错误的场景:
l = [1, 2, 3] def foo(): l += [4] foo() # 抛出错误:UnboundLocalError: local variable 'l' referenced before assignment
我们知道列表的+=是原地修改操作,不会改变对象的内存地址,行为和append类似:
x = [1, 2, 3] old_id = id(x) x += [4] new_id = id(x) assert old_id == new_id # 执行前后对象id一致,说明是原地操作
但换成append方法就能正常运行:
l = [1, 2, 3] def foo(): l.append(4) print(l) foo() # 输出:[1, 2, 3, 4]
背后的原因
这和Python的变量作用域规则直接相关,和底层优化无关:
- Python编译函数代码时,会扫描所有赋值操作。只要函数内部出现对变量
l的赋值(哪怕是+=这种原地操作的语法),就会将l标记为局部变量。 - 执行
l += [4]时,Python会先尝试读取局部变量l,但此时局部的l并未定义,因此直接抛出UnboundLocalError。 - 而
l.append(4)只是调用变量的方法,没有赋值行为,Python会按照LEGB作用域规则(局部→闭包→全局→内置)查找l,最终找到全局作用域中的l,所以能正常执行。
解决办法
如果要让+=在函数内正常运行,有两种常用方式:
- 用
global声明变量为全局变量:
l = [1, 2, 3] def foo(): global l l += [4] foo()
- 将列表作为参数传入函数:
l = [1, 2, 3] def foo(arr): arr += [4] foo(l)
内容的提问来源于stack exchange,提问作者colidyre
相关产品推荐
相关产品推荐

