使用ipythonparallel(或其他包)并行任务,这取决于不可拾取的对象

2024-06-16 11:46:49 发布

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

我经常遇到这样的问题:我想快速地在一组很多很多物体上做一件简单的事情。我经常用它的简单性来处理不愉快的事物。在尝试了几个小时之后,我通常会让自己在一台计算机上通宵运行tak,或者做一些愚蠢的事情,比如半手工地将任务划分成多个python脚本来运行。在

举一个具体的例子,假设我想删除给定S3桶中的所有键。在

我通常会不假思索地做:

import boto
from IPython.parallel import Client

connection = boto.connect_s3(awskey, awssec)
bucket = connection.get_bucket('mybucket')

client = Client()
loadbalancer = c.load_balanced_view()

keyList = list(bucket.list())
loadbalancer.map(lambda key: key.delete(), keyList)

问题是boto中的Key对象不可拾取(*)。对我来说,这种情况经常发生在不同的环境中。多处理、execnet和我尝试过的所有其他框架和lib也是一个问题(原因很明显:它们都使用相同的pickler来序列化对象)。在

你们也有这些问题吗?有没有方法可以序列化这些更复杂的对象?我是否必须为这些特定对象编写自己的pickler?如果我这么做了,如何告诉ipythonparallel使用它?我怎么写泡菜?在

谢谢!在


(*)我知道我可以简单地列出密钥名称,然后执行以下操作:

^{pr2}$

并在IPython集群的每个引擎中定义getKey函数。这只是我经常发现的一个更普遍的问题的一个具体例子。也许这是一个不好的例子,因为它可以很容易地用另一种方法来解决。在


Tags: 对象keyimportclient序列化bucketipythonconnection
2条回答

IPython有一个use_dill选项,如果安装了dill序列化程序,则可以序列化大多数“不可压缩”的对象。在

How can I use dill instead of pickle with load_balanced_view

IPython肯定能把人们聚在一起;)。所以从我收集到的数据来看,pickle对象的问题是它们的方法。所以,也许不用key的方法来删除它,你可以编写一个函数来获取它并删除它。也许首先得到一个dict的列表,其中包含每个键的相关信息,然后调用一个函数delete_key( dict ),因为我不知道如何处理s3键。在

这样行吗?在


或者,也可以这样做:只需调用实例的方法,而不是调用实例的方法,而是用实例作为参数调用类的方法。所以代替lambda key : key.delete()你应该做lambda key : Key.delete(key)。当然,您必须将类推送到节点,但这应该不是问题。一个最小的例子:

 class stuff(object):
       def __init__(self,a=1):
            self.list = []
       def append(self, a):
            self.list.append(a)

  import IPython.parallel as p
  c = p.Client()
  dview = c[:]

  li = map( stuff, [[]]*10 ) # creates 10 stuff instances

  dview.map( lambda x : x.append(1), li ) # should append 1 to all lists, but fails

  dview.push({'stuff':stuff}) # push the class to the engines
  dview.map( lambda x : stuff.append(x,1), li ) # this works.

相关问题 更多 >