gpt4 book ai didi

python - 为什么我不能在 multiprocessing.Pool 中使用 operator.itemgetter?

转载 作者:太空狗 更新时间:2023-10-29 21:47:14 24 4
gpt4 key购买 nike

以下程序:

import multiprocessing,operator
f = operator.itemgetter(0)
# def f(*a): return operator.itemgetter(0)(*a)
if __name__ == '__main__':
multiprocessing.Pool(1).map(f, ["ab"])

失败并出现以下错误:

Process PoolWorker-1:
Traceback (most recent call last):
File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
self.run()
File "/usr/lib/python3.2/multiprocessing/process.py", line 116, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.2/multiprocessing/pool.py", line 102, in worker
task = get()
File "/usr/lib/python3.2/multiprocessing/queues.py", line 382, in get
return recv()
TypeError: itemgetter expected 1 arguments, got 0

为什么我会收到错误(在 Linux x64 上的 cPython 2.7 和 3.2 上),如果我取消注释第三行,为什么它会消失?

最佳答案

这里的问题是 multiprocessing 模块通过复制将对象传递到其他进程(很明显),并且 itemgetter 对象不能使用任何明显的方法复制:

In [10]: a = operator.itemgetter(0)
Out[10]: copy.copy(a)
TypeError: itemgetter expected 1 arguments, got 0

In [10]: a = operator.itemgetter(0)
Out[10]: copy.deepcopy(a)
TypeError: itemgetter expected 1 arguments, got 0

In [10]: a = operator.itemgetter(0)
Out[10]: pickle.dumps(a)
TypeError: can't pickle itemgetter objects

# etc.

问题甚至不在于尝试在其他进程中调用 f;它首先试图复制它。 (如果您查看我在上面省略的堆栈跟踪,您会看到更多关于失败原因的信息。)

当然通常这并不重要,因为动态构建新的 itemgetter 与复制一个几乎一样简单高效。这就是您的替代“f”函数正在做的事情。 (当然,复制一个动态创建 itemgetter 的函数不需要复制 itemgetter。)

您可以将“f”变成一个 lambda。或者编写一个简单的函数(命名或 lambda)来做同样的事情而不使用 itemgetter。或者编写一个可复制的 itemgetter 替代品(这显然不会那么难)。但是您不能按您想要的方式直接使用 itemgetter 对象。

关于python - 为什么我不能在 multiprocessing.Pool 中使用 operator.itemgetter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11235054/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com