我需要通过在硬盘驱动器上存储Python字典来释放RAM,而不是在RAM中。可能吗?

时间:2010-08-02 23:54:25

标签: python

在我的例子中,我有一个大约6000个实例化类的字典,其中每个类有1000个属性变量,所有类型字符串或字符串列表。当我建立这个词典时,我的RAM上升得非常高。有没有办法写字典,因为它是建立在硬盘驱动器而不是RAM,以便我可以节省一些内存?我听说过一种叫做“泡菜”的东西,但我不知道这对我正在做的事情是否可行。

感谢您的帮助!

4 个答案:

答案 0 :(得分:5)

也许您应该使用数据库,但请查看shelve模块

如果搁置对你来说不够强大,那么总有工业强度ZODB

答案 1 :(得分:3)

正如@gnibbler推荐的那样,

shelve是我无疑会使用的,但请注意两个陷阱:一个简单的陷阱(所有键必须是字符串)和一个微妙的陷阱(因为值不是' t通常存在于内存中,在它们上面调用mutators可能无法正常工作)。

对于简单的问题,通常很容易找到一种解决方法(如果您忘记并尝试使用int或其他任何键作为密钥,您会得到一个明确的例外,所以记住你并不难确实需要解决方法)。

对于微妙的问题,请考虑例如:

x = d['foo']
x.amutatingmethod()
...much later...
y = d['foo']
# is y "mutated" or not now?

上一条评论中问题的答案取决于d是否是真正的字典(在这种情况下y将被变异,实际上与x完全相同的对象)或shelf(在这种情况下,y将成为x的独特对象,并且恰好处于您已保存d['foo']的状态!)。

要让你的突变持续存在,你需要通过

“将它们保存到磁盘”
d['foo'] = x

x上调用你想要的任何mutator后(特别是你不能只做

d['foo'].mutator()

并且期望突变“坚持”,就像d是dict一样。)

shelve 可以选择在内存中缓存所有已获取的项目,但当然可以再次填满内存,会导致长时间延迟当你最终关闭shelf对象时(因为所有缓存的项目必须保存回磁盘,以防它们 已经发生变异)。这个选项是我最初推动的(作为Python核心提交者),但我已经改变了主意,现在我为它进入道歉道歉(好吧,至少它不是默认的! - ),因为它的情况应该用于罕见的,它可以经常陷阱粗心的用户...抱歉。

BTW,如果您不知道什么是mutator或“mutating method”,那么它就是改变您调用它的对象状态的任何方法 - 例如.append如果对象是列表,.pop如果对象是任何类型的容器,依此类推。当然,如果对象是不可变的,则无需担心(数字,字符串,元组,冻结......),因为在这种情况下它没有变异方法; - )。

答案 2 :(得分:2)

一遍又一遍地腌制整个哈希必然会遇到你现在面临的相同内存压力 - 可能更糟糕的是,所有数据来回聚集。

相反,使用就像哈希的磁盘数据库可能是最好的选择;有关在程序中使用dbm样式数据库的快速介绍,请参阅此页面:http://docs.python.org/library/dbm

它们的行为就像哈希一样,它应该是一个简单的过渡。

答案 3 :(得分:1)

“”“我有一个大约6000个实例化类的字典,其中每个类有1000个属性变量,所有类型字符串或字符串列表”“”......我猜你的意思是:“”“我有一个类大约有1000个属性strlist str。我有一个字典映射关于6000个未指定类型的 到该类的相应实例。 “”如果这不是一个合理的翻译,请更正。

首先,类中的1000个属性是令人难以置信的。您必须使用value = getattr(obj, attr_name)setattr(obj, attr_name, value)一般地对待绝大多数人。请考虑使用dict而不是实例:value = obj[attr_name]obj[attr_name] = value

其次,这600万属性中有多少百分比是“”?如果足够高,您可能会考虑使用__missing__挂钩 - docs here来实现一个稀疏的dict,它实际上没有这些属性的条目。