我不能用一个简单的例子再现这个错误,而且我的代码太复杂了,无法发布。如果我用I Python shell而不是普通的Python来运行程序,事情会很顺利。 我查阅了以前关于这个问题的一些笔记。它们都是由使用池调用类函数中定义的函数引起的。但对我来说不是这样。
I Python shell
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
我很感激你的帮助。 更新:函数I pickle是在模块的顶层定义的。尽管它调用包含嵌套函数的函数。i、 e,f()调用g()调用h(),h()有一个嵌套函数i(),我正在调用pool.apply_async(f)。f()、g()、h()都是在顶层定义的。我用这个模式尝试了一个更简单的例子,但还是成功了。
I pickle
i、 e,f()
g()
h()
h(
i()
pool.apply_async(f)
f()
这是一份可以腌制的东西的清单。特别是,函数只有在模块的顶层定义时才是可选择的。 这段代码:
import multiprocessing as mp class Foo(): @staticmethod def work(self): pass if __name__ == '__main__': pool = mp.Pool() foo = Foo() pool.apply_async(foo.work) pool.close() pool.join()
产生的错误几乎与你发布的错误相同:
Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 505, in run self.__target(*self.__args, **self.__kwargs) File "/usr/lib/python2.7/multiprocessing/pool.py", line 315, in _handle_tasks put(task) PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
问题在于,pool所有方法都使用a mp.SimpleQueue将任务传递给工作进程。mp.SimpleQueue必须经过的所有内容都必须是可选取的,并且foo.work不可选取,因为它不是在模块的顶层定义的。
pool
a mp.SimpleQueue
mp.SimpleQueue
可以通过在顶层定义一个函数来修复该问题,该函数调用foo.work():
foo.work()
def work(foo): foo.work() pool.apply_async(work,args=(foo,))
请注意,它foo是可拾取的,因为它Foo是在顶层定义的并且 foo.__dict__是可拾取的。
foo.__dict__