【问题标题】:python multiprocessing : AttributeError: Can't pickle local objectpython多处理:AttributeError:无法腌制本地对象
【发布时间】:2020-09-22 22:35:20
【问题描述】:

我在一个类中有一个方法可以返回一个参数可能会改变的函数。

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

方法一、二:

 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 作为接口的参数。

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

【问题讨论】:

  • 您的示例无法运行,这使得尝试解决方案变得更加困难。
  • @tdelaney 抱歉,我之前犯了一个错误。我更改了代码,但它引发了异常。
  • 我看不到链接的问题如何回答这个问题。在那里,OP 可以将函数移到模块级别,但这里不是这种情况,因为调用也有需要管理的状态。

标签: python


【解决方案1】:

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)

【讨论】:

  • 感谢您的建议。你会分享一些“Python 不能腌制闭包”的文档吗?我在“python.org”找不到相关信息。
猜你喜欢
  • 2022-01-02
  • 2022-11-16
  • 1970-01-01
  • 2021-06-17
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
相关资源
最近更新 更多