如何 pickle Python class 方法?

How can I pickle a Python class method?

在 Python 3.6 上,我定义了一个 class foo 来实例化一个对象 p。在实例化时,class 执行计算量大的插值,'attaches' 对对象执行插值函数。

完成此操作后,我可以调用其他 class 方法而无需再次进行插值。到目前为止,还不错。

下面的代码显示了一个最小的工作示例:

import numpy as np
from scipy.integrate import quad
from scipy.interpolate import interp1d

class foo(object):
    def __init__(self):
        self.func = self.interp()


    def interp(self):
        def integrand(x): return self.shape(x)

        xpoints = np.arange(100)
        ypoints = [quad(
                        integrand, a=-np.inf, b=np.inf
                        )[0]/x for x in xpoints]

        I = interp1d(xpoints, ypoints)
        return I


    def shape(self, x):
        F = x**2  # complicated maths here
        return F

然后我使用 p 对象来执行繁重的任务。我将它并行化以进行优化。我像这样使用 multiprocessing 库:

import multiprocessing as mp

with mp.Pool(mp.cpu_count()) as pool:
    results = pool.map(func, list(bar))  # func uses my p instance

为此我得到一个错误 MaybeEncodingError: Error sending result...,它的回溯指向我的插值函数是 unpickleable。

我不知道如何 pickle interp1d 并且我不想更改我当前代码的结构,因为这已经经过深思熟虑并且我认为它是最有效的格式。我可以添加另一(几)行以使我的插值函数成为顶级吗?

我试过使用 joblib,它一直抱怨内存问题(即使使用了 1 cpu)。

就我而言,multiprocessing 确实可以胜任。它实际上完成了工作,在终端中输出结果,但未能将所有结果收集在一起。我并行化的可迭代对象中的所有项目都是完全独立的。

池使用多处理队列在进程之间传输数据。这些队列只适用于 pickleable 数据。腌制函数只是按名称存储并由 unpickler 重新导入。当然,这意味着它们必须是可导入的。

通常有一些方法可以解决这些酸洗问题,但为了省去麻烦,请安装 pathos。它的多处理池使用 dill 几乎可以腌制任何东西。