使用python的多处理模块分发作业

2024-09-30 02:26:15 发布

您现在位置:Python中文网/ 问答频道 /正文

问题描述

我有一些代码我刚开始尝试在Python3.5中加速。我正试图用multiprocessing模块来实现这一点。下面是一个最简单的例子来演示我要做的。在

串行地,代码更直接。Momma_Serial类中有一个Baby对象的列表。有时,我们希望对每一个调用Baby.evolve()方法。实际上,将会有很多这样的Baby对象(本例中只有100个)。这就是寻求平行性的最初动机。在

使整个过程复杂化的是,程序的顶层通过传递一个函数pass_this_func()来告诉每个Baby对象是如何做到的。这个函数是Momma_Serial.evolve_all_elems()的一个参数,并传递给这个momma对象中的所有小宝贝对象。在

class Baby:
    def __init__(self, lol):
        self.lol = lol

    def evolve(self, f):
        self.lol = f(self.lol)

def pass_this_func(thing):
    return( 2 * thing )        

class Momma_Serial:
    def __init__(self, num):
        self.my_list = [Baby(i) for i in range(num)]

    def evolve_all_elems(self, the_func):
        for baby in self.my_list:
            baby.evolve(the_func)


momma1 = Momma_Serial(100)
[baby.lol for baby in momma1.my_list]
momma1.evolve_all_elems(pass_this_func)
[baby.lol for baby in momma1.my_list]

这是应该的。但很慢。下面是我使用多处理模块重新编写Momma类的尝试。在

^{pr2}$

我试着运行它:

momma2 = Momma_MP(100)
[baby.lol for baby in momma2.my_list]
momma2.evolve_all_elems(pass_this_func) #error comes here
# [baby.lol for baby in momma2.my_list]

但我得到了一个错误:

AttributeError: Can't pickle local object 'Momma_MP.evolve_all_elems.<locals>.f'

this stackoverflow question状态的回答“函数只有在模块的顶层定义时才是可选择的。”这句话似乎是实现这一点的唯一方法是在Momma_MP类之外定义一个函数。但我真的不想这么做,因为这会给我的代码带来更多的问题。在

我的问题##

(编辑了一下) 有什么解决办法吗?假设我不能在类之外定义映射函数。还假设Momma()没有在__main__顶级脚本环境中实例化。另外,我不想偏离这个程序设计太多,因为我希望所有这些Baby()实例都被抽象出来;我不希望实例化实例或与Momma()实例交互的地方/程序不得不担心或知道与Baby()类有关的任何事情。这些额外的限制使问题与情况here略有不同。在

顺便说一句,下面的代码不会抛出错误,但是可能会有一些复制操作在进行,因为组成的Baby对象没有发生任何变化。在

def outside_f(obj):
    obj.evolve(pass_this_func)       

class Momma_MP:
    def __init__(self, num):
        self.my_list = [Baby(i) for i in range(num)]

    def evolve_all_elems(self, the_func):
        num_workers = 2            

        with mp.Pool(num_workers) as pool:        
            pool.map(outside_f, self.my_list)        

momma2 = Momma_MP(100)
[baby.lol for baby in momma2.my_list]
momma2.evolve_all_elems(pass_this_func)
[baby.lol for baby in momma2.my_list] # no change here?

Tags: inselfformydefallthislist
1条回答
网友
1楼 · 发布于 2024-09-30 02:26:15

我将尝试给出一个我可以找到的其他地方没有涵盖的答案(见我上面的评论)。我假设你有不同种类的Momma,它们有不同的f()函数。在

您可以创建一个函数evolver()

def evolver(baby):
   momma = baby.momma
   momma.evolve(baby)

您需要在Baby__init__()中分配{},将{}实例传递给Baby

^{pr2}$

现在您将从Momma派生来重写evolve()方法来专门化evolve()函数。在

所以现在当您调用pool.map(evolver, babies)时,它将把baby传递给evolver(),然后请求momma给{}baby。在

我在上面链接的一个答案是,你也可以做以下事情:

class Momma:
    evolver = staticmethod(evolver)

…将全局方法放入类中。在

相关问题 更多 >

    热门问题