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

标签 python multiprocessing python-multithreading

以下程序:

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/

相关文章:

python - eval() 函数如何改变字典?

python - Tensorflow:为什么 inception_v3 预测在评估中是 Nan?

Python 多重处理

python - Dask - 是否可以通过自定义函数使用每个工作线程中的所有线程?

python - 为什么Python多处理管理器会产生线程锁?

python - Pyccuracy selenium-server.jar 有 22 个字节?

python - 将参数值从文件传递到 numba 类

Python 多处理永远运行

python - 登录多处理和多线程python程序?

python-3.x - python asyncio 无法异步运行两个无限函数