【问题标题】:allow a shelve object to be pickled in python, pypar and mpich2允许在 python、pypar 和 mpich2 中腌制搁置对象
【发布时间】:2011-07-13 05:09:59
【问题描述】:

我有一些遗留的 python 代码,它们使用 pypar 和 mpich2 在多个节点之间传输数据。出于某种原因,数据保存在架子上,pypar 想要腌制架子以将其发送到其他节点。不允许酸洗货架。所以我想从搁置转换为我可以通过 pypar 发送的东西,它在发送到其他节点之前对其进行腌制。有什么建议?我可以将搁置转换为 json 并腌制吗?

【问题讨论】:

    标签: python json pickle mpi shelve


    【解决方案1】:

    尝试将搁置转换为dict(),然后对其进行酸洗:

    sdb = shelve.open('foo.db')
    sdb['abc'] = {'a': 1, 'b': 2}
    tmp = cPickle.dumps(dict(sdb), 2)
    print cPickle.loads(tmp)
    {'abc': {'a': 1, 'b': 2}}
    

    更新:(对 cme​​ts 中的问题的回应):dict 可以从任何映射对象复制键值,因此如果该对象实现了方法 keys__getitem__它会起作用的。由于搁置是一个映射对象,dict 复制构造函数可以从搁置中读取键值,然后您可以腌制得到的 dict 并将其发送到其他主机。

    以下示例显示了复制对象所需的最小接口dict

    class Foo(object):
    
        def __init__(self):
            self.value = 0
    
        def keys(self):
            return ['a', 'b']
    
        def __getitem__(self, key):
            v = self.value
            self.value += 1
            return self.value
    
    foo = Foo()
    print dict(foo)
    print dict(foo)
    

    输出

    {'a': 1, 'b': 2}
    {'a': 3, 'b': 4}
    

    更新:要将字典的内容添加回搁置,请使用update()

    d = {'a': 1, 'b': 2}
    s = shelve.open('foo.db')
    s.update(d)
    print s
    {'a': 1, 'b': 2}
    

    【讨论】:

    • 所以我只使用 dict(shelve-object)?
    • 是的,shelve 是一个 DictMixin,这意味着它的行为就像一个 dict,因此可以将它传递给 dict 的构造函数,该构造函数将复制其内容。我将更新我的答案,提供更多说明。
    • 这可能很明显,但我如何将 dict 转回搁置?
    【解决方案2】:

    @samplebias's suggestion 将您的搁置对象转换为字典将起作用。

    但是,(这可能是一个长镜头,但是)考虑到您的数据已经搁置到一个 db 文件中,可能值得检查让其他节点从数据库中加载数据是否更快搁置文件而不是进行 MPI 发送。我假设所有节点都可以访问同一个文件系统,因为您使用 MPI 运行它们。

    老实说,我希望 MPI 发送速度更快,特别是如果您在共享内存系统上运行,因为许多 MPI 实现将回退到内存副本。但是,一旦您将发送的重新酸洗和取消酸洗的开销包括在内,比赛可能会很接近!

    我怀疑这将取决于您运行它的节点数量以及您的通信模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-15
      • 2020-04-07
      • 2015-08-24
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多