Python多处理PicklingError:无法pickle

发布于 2021-02-02 23:20:18

我不能用一个简单的例子再现这个错误,而且我的代码太复杂了,无法发布。如果我用I Python 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

我很感激你的帮助。
更新:函数I pickle是在模块的顶层定义的。尽管它调用包含嵌套函数的函数。i、 e,f()调用g()调用h()h()有一个嵌套函数i(),我正在调用pool.apply_async(f)f()g()h()都是在顶层定义的。我用这个模式尝试了一个更简单的例子,但还是成功了。

关注者
0
被浏览
134
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    这是一份可以腌制的东西的清单。特别是,函数只有在模块的顶层定义时才是可选择的。
    这段代码:

    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不可选取,因为它不是在模块的顶层定义的。

    可以通过在顶层定义一个函数来修复该问题,该函数调用foo.work()

    def work(foo):
        foo.work()
    
    pool.apply_async(work,args=(foo,))
    

    请注意,它foo是可拾取的,因为它Foo是在顶层定义的并且 foo.__dict__是可拾取的。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看