Python multiprocessing PicklingError报错原因与pathos解决方案
本文分析Python multiprocessing模块中调用类内函数时触发的PicklingError错误。由于原生pickle仅支持顶层定义的对象,类方法无法被序列化导致报错。通过引入pathos库(基于dill)或手动实现序列化,可有效解决该问题,实现类方法的并行处理。
Python multiprocessing PicklingError报错原因与pathos解决方案
本文详细解析Python中multiprocessing pool模块引发PicklingError错误的成因及解决方法,旨在为开发者提供实用的排查思路与修复方案。
问题描述
问题描述
在使用multiprocessing模块的pool函数处理类内部方法时,常会遭遇如下错误提示:
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
查阅Python官方文档可知,原生pickle模块仅支持序列化特定类型的对象,具体包括:
- None、True 和 False
- 整数、浮点数及复数
- 字符串、字节串及字节数组
- 仅包含可序列化对象的元组、列表、集合和字典
- 在模块顶层使用def定义的函数(排除lambda表达式)
- 在模块顶层定义的内建函数
- 在模块顶层定义的类
- 上述类的实例,且其__dict__或getstate()返回值可被序列化(详见Pickling Class Instances章节)。
- Pickling Class Instances for details).
错误成因分析
由此可见,原生pickle仅允许序列化顶层定义的函数。由于类内部的方法不属于顶层定义,因此无法被序列化,进而导致上述报错。
import multiprocessing
def work(): # top-level 函数
print "work!"
class Foo():
def work(self): # 非top-level函数
print "work"
pool1 = multiprocessing.Pool(processes=4)
foo = Foo()
pool1.apply_async(foo.work)
pool1.close()
pool1.join()
# 此时报错
pool2 = multiprocessing.Pool(processes=4)
pool2.apply_async(work)
pool2.close()
pool2.join()
# 此时工作正常
解决方案
解决方案
推荐使用pathos包中的multiprocessing模块替代原生模块。pathos底层利用dill库重写序列化逻辑,dill能够序列化绝大多数Python对象,从而解决类方法无法被pickle的问题。此外,也可自行基于dill封装序列化逻辑,但此举略显冗余。
参考资源
参考资源
1. https://stackoverflow.com/questions/8804830/python-multiprocessing-picklingerror-cant-pickle-type-function 2. https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled 3. https://github.com/uqfoundation/pathos
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python进程与线程操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》、《Python+MySQL数据库程序设计入门教程》及《Python常见数据库操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













