You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内.append与+=的差异及Pool.apply_async回调赋值报错解析

为什么在multiprocessing回调函数中使用results += [t]会报错,而append却正常?

这是个很有意思的问题,本质和多进程或者回调机制本身无关,核心是Python中可变对象的操作方式与变量作用域的区别。

先看你提供的代码:

from multiprocessing import Pool
import random
results = []
def f(t):
    return t
def cb_append_result(t):
    # 报错:"local variable 'results' referenced before assignment"
    # results += [t]
    # 正常运行
    results.append(t)
if __name__ == '__main__':
    pool = Pool()
    t = random.random()
    pool.apply_async(f,args=(t,),callback=cb_append_result)
    pool.close()
    pool.join()
    print("Result is {}".format(results))

问题原因分析

  • results.append(t):这是在原列表对象上进行的原地修改操作。Python会先在当前函数作用域查找results,找不到就自动去外层全局作用域寻找,找到后直接调用它的append方法——整个过程没有改变results变量本身的指向,因此不需要额外声明作用域。
  • results += [t]:这个操作等价于results = results + [t],本质是创建了一个新的列表对象,并把results变量重新赋值指向这个新对象。Python解释器看到赋值操作时,会默认把results当作当前函数的局部变量,但此时局部作用域里还未定义results,就会抛出“局部变量未赋值即引用”的错误。

解决方案

要让results += [t]正常运行,只需要在回调函数里声明results是全局变量,告诉解释器去全局作用域查找这个变量:

def cb_append_result(t):
    global results
    results += [t]

这样解释器就不会把results当作局部变量处理,而是直接使用全局作用域中的列表,执行赋值操作时也会正确更新全局变量的指向。

内容的提问来源于stack exchange,提问作者Donna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:47:03