python multiprocessing:AttributeError:无法腌制本地对象

时间:2020-06-04 03:09:16

标签: python

我在类内部有一个方法来返回一个函数,参数可能会更改。

Interface函数接受两个参数f和其args。我想使用mp.pool对其进行加速,但是它返回错误。

from multiprocessing import Pool
# from multiprocess import Pool
# from pathos.multiprocessing import ProcessingPool as Pool
import pickle
import dill


class Temp:
    def __init__(self, a):
        self.a = a

    def test(self):
        def test1(x):
            return self.a + x

        return test1


def InterfaceFunc(f, x):
    mypool = Pool(4)
    return list(mypool.map(f, x))


if __name__ == "__main__":
    t1 = Temp(1).test()
    x = [1, 2, 3, 1, 2]

    res1 = list(map(t1, x))
    print(res1)

    res2 = InterfaceFunc(t1, x)

它会引发相同的错误:

AttributeError: Can't pickle local object 'Temp.test.<locals>.test1'

我尝试了3种方法:

What can multiprocessing and dill do together?

Replace pickle in Python multiprocessing lib

Python Multiprocessing Pool Map: AttributeError: Can't pickle local object

方法1、2:

 from multiprocess import Pool
 from pathos.multiprocessing import ProcessingPool as Pool

它引发错误:

 File "E:\Users\ll\Anaconda3\lib\site-packages\dill\_dill.py", line 577, in _load_type
    return _reverse_typemap[name]
KeyError: 'ClassType'

Method3需要更改代码,但是我不能简单地将func移出类,因为我需要f作为Interface的参数。

您有什么建议吗?我是一个没有经验的新人。

1 个答案:

答案 0 :(得分:0)

Python无法腌制闭包,但是您真正需要的是可以调用的保留状态的东西。 __call__方法使一个类实例可调用,因此使用它

from multiprocessing import Pool

class TempTest1:

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

    def __call__(self, x):
        return self.a + x

class Temp:
    def __init__(self, a):
        self.a = a

    def test(self):
        return TempTest1(self.a)

def InterfaceFunc(f, x):
    mypool = Pool(4)
    return list(mypool.map(f, x))

if __name__ == "__main__":
    t1 = Temp(1).test()
    x = [1, 2, 3, 1, 2]

    res1 = list(map(t1, x))
    print(res1)

    res2 = InterfaceFunc(t1, x)
    print(res2)