【问题标题】:MultiProcessing with self.methods使用 self.methods 进行多处理
【发布时间】:2017-04-06 09:39:54
【问题描述】:

在方法上使用 multiprocessing 会收到错误声明 self.methods cannot be pickled

为了克服这个问题,我使用了:

def _pickle_method(m):
    if m.im_self is None:
        return getattr, (m.im_class, m.im_func.func_name)
    else:
        return getattr, (m.im_self, m.im_func.func_name)


copy_reg.pickle(types.MethodType, _pickle_method)

现在我搜索了这个,但仍有几个问题不清楚:

  1. 为什么self.methods不能腌制?
  2. copy_reg.pickle() 是如何工作的?它如何启用self.methods 的酸洗?
  3. 使用这种方法是否有负面影响,或者还有其他更好的方法吗?

更多信息:

我在一个类中有一个函数,该函数用于执行 request.getrequest.post。为了提高时间,我在它上面使用了多处理。 这正是我面临的问题。

SO Question

【问题讨论】:

  • 如果没有更多信息,很难理解为什么 pickle 会尝试序列化一个实际的类方法(pickle 不是这样做的)——所以这是可能的答案是“如果你需要这样做,那么你做错了其他事情。”请edit您的问题并添加更多上下文。
  • self.methods 到底是什么?如果可能,请使用执行request.getrequest.post(以及相关的多处理)的方法来展示该类。
  • @martineau 我只是使用了 self.mathods 这个名字......它们只是任何采用 self 的类方法......代码可以在链接的 SO 帖子中找到...... .相同或相似

标签: python pickle python-multiprocessing


【解决方案1】:

您的预期用途仍然有点模糊,因此我将在您的问题的新“更多信息”部分中展示一种解决 linked question 的方法,该方法不需要酸洗类的字节码方法。我认为它是如何做到的很明显......

someclass.py

import multiprocessing

def call_method(x):
    return SomeClass().f(x)

class SomeClass(object):
    def __init__(self):
        pass

    def f(self, x):
        return x*x

    def go(self):
        pool = multiprocessing.Pool(processes=4)
        print pool.map(call_method,  range(10))

test.py

import someclass

if __name__== '__main__' :
    sc = someclass.SomeClass()
    sc.go()

输出:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

【讨论】:

  • pickle 不序列化代码。它存储了有关任何需要保存的足够信息,以便可以在需要时导入。 copy_reg() 函数在 online documentation 中描述。这是一种将函数与特定数据类型关联(注册)的方法。当尝试序列化遇到的任何指定类型的对象时,将调用此函数。
  • 哦,好吧....搞清楚了...只剩下一个问题....为什么不能多进程pickle self.methods,而在使用普通函数时可以。有问题的SO链接确实解释一下,但你能不能更清楚一点。M 仍然不确定那部分。
  • @vks:我不确定你所说的“正常功能”是什么意思。无需腌制内置函数,因为它们始终可用。
猜你喜欢
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2017-10-09
相关资源
最近更新 更多