首页 > 解决方案 > multiprocessing.Pool 不能返回带有附加参数的 OrderedDict 子类

问题描述

我试图让一个简单的子类OrderedDictPool然后返回。

似乎将创建的对象返回到池中时的酸洗过程会尝试重新实例化该对象,但由于__init__函数中需要额外的参数而失败。

这是一个最小(非)工作示例:

from collections import OrderedDict
from multiprocessing import Pool


class Obj1(OrderedDict):
    def __init__(self, x, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.x = x


def task(x):
    obj1 = Obj1(x)
    return obj1


if __name__ == '__main__':
    with Pool(1) as pool:
        for x in pool.imap_unordered(task, (1,2,3)):
            print(x.x)

如果我这样做,我会收到以下错误。

线程 Thread-3 中的异常:回溯(最后一次调用):文件“/usr/lib/python3.6/threading.py”,第 916 行,在 _bootstrap_inner self.run() 文件“/usr/lib/python3. 6/threading.py”,第 864 行,在运行 self._target(*self._args, **self._kwargs) 文件“/usr/lib/python3.6/multiprocessing/pool.py”,第 463 行,在 _handle_results task = get() File "/usr/lib/python3.6/multiprocessing/connection.py", line 251, in recv return _ForkingPickler.loads(buf.getbuffer()) TypeError: init () missing 1 required positional argument: 'X'

task函数返回池时,这又失败了,我猜对象被腌制了?

如果我OrderedDict通过一个简单的更改dict它可以完美地工作......

我有一个解决方法来使用kwargs和检索感兴趣的属性,但我对一开始的错误感到困惑。有任何想法吗?

标签: python-3.xmultiprocessing

解决方案


您可以为您的类定义__getstate__()__setstate__()方法。

在这些功能中,您可以确保也x可以处理。例如:

def __getstate__(self):
    return self.x, self.items()

def __setstate__(self, state):
    self.x = state[0]
    self.update(state[1])

顺便说一句,从 CPython 3.6 开始,没有理由使用OrderedDict,因为字典顺序是插入顺序。这最初是 CPython 中的一个实现细节。在 Python 3.7 中,它成为了语言的一部分。


推荐阅读