Python multiprocessing调用其他模块函数返回空列表问题及解决
问题原因
你遇到的问题根源是Python多进程的启动机制与导入语句的位置不匹配:
Windows系统默认采用spawn模式创建子进程,子进程启动时会重新导入整个主脚本文件。而你将from Testing.test import add_one写在了if __name__ == "__main__"代码块内部,子进程导入主脚本时不会执行该代码块,导致randomize_data函数运行时找不到add_one函数直接报错,任务未完成所以最终返回空列表。
你提到升级Spyder到5.0.5后问题解决,是因为旧版Spyder的控制台运行环境对多进程的兼容存在缺陷,升级后环境适配了特殊的导入逻辑,但你的原有代码在原生Python环境、其他IDE中运行依然会触发报错,建议按标准写法修正。
解决方案
方案1:调整导入语句位置
将add_one的导入移到脚本最顶部,和其他依赖的导入语句放在一起,确保子进程导入主脚本时能成功加载该函数:
import multiprocessing import numpy as np import pandas as pd from Testing.test import add_one # 移到全局导入位置 def randomize_data(mean, cov, n_init, proc_num, return_dict): result = pd.DataFrame() for _ in range(n_init): temp = np.random.multivariate_normal(mean, cov) result = result.append(pd.Series(temp), ignore_index=True) result = add_one(result) return_dict[proc_num] = result if __name__ == "__main__": mean = np.arange(0, 1, 0.1) cov = np.identity(len(mean)) manager = multiprocessing.Manager() return_dict = manager.dict() jobs = [] for i in range(5): p = multiprocessing.Process(target=randomize_data, args=(mean, cov, 2000, i, return_dict, )) jobs.append(p) p.start() for proc in jobs: proc.join() result = list(return_dict.values()) # 转成列表更方便后续处理
方案2:将函数作为参数传入子进程
如果不想全局导入第三方模块的函数,可以直接把add_one作为参数传给子进程,进程启动时会自动序列化传递该函数:
只需修改两个位置即可:
- 调整
randomize_data的参数定义,新增add_one接收项
def randomize_data(mean, cov, n_init, proc_num, return_dict, add_one): # 函数内部逻辑保持不变
- 创建子进程时传入
add_one参数
p = multiprocessing.Process(target=randomize_data, args=(mean, cov, 2000, i, return_dict, add_one))
内容的提问来源于stack exchange,提问作者Ricky The Ising
相关产品推荐
相关产品推荐

