我有一个对象列表,需要调用每个对象的成员函数。是否可以使用多处理来实现这一点?
我写了一个简短的例子来说明我想做的事情。
import multiprocessing as mp
class Example:
data1 = 0
data2 = 3
def compute():
self.val3 = 6
listofobjects = []
for i in range(5):
listofobjects.append(Example())
pool = mp.Pool()
pool.map(listofobjects[range(5)].compute())
最佳答案
除了“伪代码”中的语法和使用问题之外,@abarnert 还指出了两个概念问题。第一个是 map
使用应用于输入元素的函数。第二个是每个子进程都会获取对象的副本,因此属性的更改不会自动在原始对象中看到。这两个问题都可以解决。
为了回答您迫在眉睫的问题,以下是如何将方法应用于您的列表:
with mp.Pool() as pool:
pool.map(Example.compute, listofobjects)
Example.compute
是一个未绑定(bind)方法。这意味着它只是一个接受 self
作为第一个参数的常规函数,使其非常适合 map
。我还使用池作为上下文管理器,建议确保无论是否发生错误都能正确完成清理。
上面的代码不起作用,因为compute
的效果对于子进程来说是本地的。将它们传递回原始进程的唯一方法是从传递给 map
的函数中返回
它们。如果你不想修改compute
,你可以这样做:
def get_val3(x):
x.compute()
return x.val3
with mp.Pool() as pool:
for value, obj in zip(pool.map(get_val3, listofobjects), listofobjects):
obj.val3 = value
如果您愿意修改compute
以返回它正在操作的对象(self
),您可以使用它来更有效地替换原始对象:
class Example:
...
def compute():
...
return self
with mp.Pool() as pool:
listofobjects = list(pool.map(Example.compute, listofobjects))
更新
如果您的对象或其引用树的某些部分不支持pickle(这是通常用于在进程之间传递对象的序列化形式),您至少可以通过直接从计算
:
class Example:
...
def compute():
self.val3 = ...
return self.val3
with mp.Pool() as pool:
for value, obj in zip(pool.map(Example.compute, listofobjects), listofobjects):
obj.val3 = value
关于python - 多重处理成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49636078/