如何解决Python程序并行处理中的TypeError: bagging_and_trees_growth() argument after ** must be a mapping, not tuple错误(pp模块在Python3中无法使用)
解决ThreadPool.apply_async引发的TypeError问题
你遇到的TypeError: bagging_and_trees_growth() argument after ** must be a mapping, not tuple错误,核心原因是**ThreadPool.apply_async的参数规则和你之前用的pp.submit完全不同**,错误地传递了依赖函数和模块参数导致的。
错误原因拆解
pp模块的submit方法支持传入依赖函数(depfun)和依赖模块(dep_modules)来确保任务在子进程中能正常运行,但multiprocessing.dummy.ThreadPool的apply_async方法根本不需要这些参数——它的参数定义是:
apply_async(func, args=(), kwds={}, callback=None, error_callback=None)
你在调用时把depfun和dep_modules当成了apply_async的后续参数,这些参数会被识别为kwds(关键字参数),但depfun是元组而非字典(映射类型),所以直接触发了类型错误。
解决方案
只需要移除apply_async调用中多余的depfun和dep_modules参数即可,因为线程池会自动继承主进程的函数和模块环境,只要这些依赖在主进程中已经导入,子线程就能正常访问。
修正后的agiled_random_forest函数代码如下:
def agiled_random_forest(samples, network, size, processes=39): rforest = [] threadPool = ThreadPool(processes=processes) # 移除了不需要的depfun和dep_modules参数,显式指定args参数更清晰 tree_num_of_each_task = int(size/processes) jobs = [threadPool.apply_async(bagging_and_trees_growth, args=(samples, network, tree_num_of_each_task)) for x in range(processes)] for job in jobs: rforest += job.get() threadPool.destroy() return rforest
额外注意事项
- 确保所有依赖的函数(比如
find_best_split、tree_growth等)和模块(networkx、numpy等)都在主脚本开头完成导入,线程池的子线程会自动共享这些资源。 - 如果
size不能被processes整除,最后可能会少生成一些树,你可以额外处理这个边界情况(比如给最后一个任务多分配剩余的树数量)。
内容的提问来源于stack exchange,提问作者Ravi Saroch
相关产品推荐
相关产品推荐

