我正在尝试一个简单的OrderedDict
子类,该子类由Pool
创建然后返回。
似乎将创建的对象返回到池时的酸洗过程会尝试重新实例化该对象,但由于__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)
如果我这样做,我会收到以下错误。
线程线程 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 任务 = 获取(( 文件 "/usr/lib/python3.6/multiprocessing/connection.py",第 251 行,在 recv 中 return _ForkingPickler.loads(buf.getbuffer((( 类型错误:init(( 缺少 1 个必需的位置参数:"x">
当task
函数返回到池中并且我猜对象被腌制时,这再次失败?
如果我通过一个简单的dict
更改OrderedDict
,它可以完美运行......
我有一个解决方法可以使用kwargs
并检索感兴趣的属性,但我对一开始的错误感到困惑。有什么想法吗?
您可以为类定义__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中,它成为语言的一部分。