3

我经常遇到一些问题,我想在一组很多很多对象上快速做一些简单的事情。我自然的选择是使用 IPython Parallel,因为它很简单,但我经常不得不处理不可拾取的对象。在尝试了几个小时之后,我通常会放弃自己在一台计算机上运行我的任务,或者做一些愚蠢的事情,比如半手动地分割东西以在多个 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)

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

你们也有这些问题吗?有没有办法可以序列化这些更复杂的对象?我是否必须为这个特定的对象编写自己的pickler?如果我这样做了,我如何告诉 IPython Parallel 使用它?我如何写一个pickler?

谢谢!


(*) 我知道我可以简单地列出键名并执行以下操作:

loadbalancer.map(lambda keyname: getKey(keyname).delete())

并在 IPython 集群的每个引擎中定义getKey函数。这只是我经常发现的更普遍问题的一个特定实例。也许这是一个不好的例子,因为它可以通过另一种方式轻松解决。

4

2 回答 2

2

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

如何在 load_balanced_view 中使用 dill 而不是 pickle

于 2014-10-19T11:18:25.947 回答
0

IPython 确实将人们聚集在一起;)。因此,据我所知,酸洗对象的问题在于它们的方法。key因此,也许您可​​以编写一个函数来获取并删除它,而不是使用删除它的方法。也许首先得到一个dict包含每个键相关信息的 's 列表,然后调用一个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.
于 2013-10-23T12:25:30.690 回答