首页 > 解决方案 > Python Multiprocessing Pool.map 在 __new__ 中导致错误

问题描述

在下面的简单 Python 3 示例中,我们使用multiproessing模块来处理 list friends,是什么导致了错误:

类型错误:()缺少 1 个必需的位置参数:“名称”

如果只是运行不会发生错误

tom = Friend(tom)
say_hello(tom)

有什么想法可以解决这个问题吗?谢谢!

代码

import multiprocessing

def say_hello(friend):
    print('Hello', friend.name, '!')

class Friend:
    friends = {}
    def __new__(cls, name):
        if name not in cls.friends:
            cls.friends[name] = super(Friend, cls).__new__(cls)
        return cls.friends[name]

    def __init__(self, name):
        self.name = name

jack = Friend('jack')
ryan = Friend('ryan')
friends = [jack, ryan]
multiprocessing.Pool(2).map(say_hello, friends)

完整的错误跟踪

Traceback (most recent call last):
  File "/Users/nyxynyx/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/nyxynyx/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/nyxynyx/opt/anaconda3/lib/python3.7/multiprocessing/pool.py", line 110, in worker
    task = get()
  File "/Users/nyxynyx/opt/anaconda3/lib/python3.7/multiprocessing/queues.py", line 354, in get
    return _ForkingPickler.loads(res)
TypeError: __new__() missing 1 required positional argument: 'name'

标签: pythonpython-3.xmultiprocessingpython-multiprocessing

解决方案


这是 unpickling 期间的错误,因为在 unpicklingname期间重新创建对象时没有准备好传递。

它已经可以通过以下方式复制:

pickle.loads(pickle.dumps(jack))

Traceback (most recent call last): 
  ...
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-9-239857af5731>", line 1, in <module>
    pickle.loads(pickle.dumps(jack))
TypeError: __new__() missing 1 required positional argument: 'name'

解决方案是实施object.__getnewargs__()or object.__getnewargs_ex__()

目的。获取新参数()

此方法的目的与getnewargs_ex ()类似,但仅支持位置参数。它必须返回一个参数 args 的元组,该元组将在 unpickling 时传递给new () 方法。

如果定义了getnewargs_ex (),则不会调用getnewargs ()。

在 3.6 版更改: 在 Python 3.6 之前,在协议 2 和 3 中调用getnewargs () 而不是getnewargs_ex ()。

所以在你的情况下:

def __getnewargs__(self):
    return self.name,

推荐阅读