很抱歉,我无法用更简单的示例重现错误,而且我的代码太复杂而无法发布。如果我在 IPython shell 而不是常规 Python 中运行该程序,一切都会顺利进行。
我查了一些以前关于这个问题的笔记。它们都是由使用池调用类函数中定义的函数引起的。但对我来说情况并非如此。
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 313, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
我将不胜感激任何帮助。
更新:我 pickle 的函数定义在模块的顶层。尽管它调用了一个包含嵌套函数的函数。 ie, f()
calls g()
calls h()
which has a nested function i()
, and I am calling pool.apply_async(f)
. f()
, g()
, h()
都是在顶层定义的。我用这个模式尝试了更简单的例子,但它确实有效。
原文由 CuriousMind 发布,翻译遵循 CC BY-SA 4.0 许可协议
以下是 可以 pickle 的列表。特别是,只有在模块的顶层定义的函数才可以选择。
这段代码:
产生一个与您发布的错误几乎相同的错误:
问题是
pool
方法都使用mp.SimpleQueue
将任务传递给工作进程。通过mp.SimpleQueue
的所有内容都必须是可挑选的,并且foo.work
不可挑选,因为它未在模块的顶层定义。它可以通过在顶层定义一个函数来修复,该函数调用
foo.work()
:请注意
foo
是可挑选的,因为Foo
是在顶层定义的,而foo.__dict__
是可挑选的。