我需要通过将Python字典存储在硬盘上而不是RAM来释放内存,可以吗?

2 投票
4 回答
2723 浏览
提问于 2025-04-16 02:13

在我的情况下,我有一个字典,里面大约有6000个实例化的类,每个类都有1000个属性变量,这些变量都是字符串类型或者字符串列表。随着我不断构建这个字典,我的内存使用量变得非常高。有没有办法在构建字典的同时,把它写入硬盘,而不是一直占用内存,这样我就可以节省一些内存?我听说过一种叫“pickle”的东西,但我不知道这是否适合我现在的情况。

谢谢你的帮助!

4 个回答

2

一次又一次地把整个哈希表进行“打包”处理,肯定会遇到你现在所面临的内存问题——甚至可能更糟,因为数据在来回传输时会消耗更多内存。

与其这样,不如使用一种在硬盘上存储的数据库,它的功能类似于哈希表,这样可能是更好的选择;你可以看看这个页面,快速了解如何在你的程序中使用dbm风格的数据库:http://docs.python.org/library/dbm

这些数据库的工作方式和哈希表很相似,所以你应该能很容易地过渡到这种方式。

3

shelve,正如@gnibbler所推荐的那样,是我肯定会使用的,但要注意两个陷阱:一个简单的(所有的键必须是字符串)和一个微妙的(因为值通常不在内存中,所以对它们调用修改方法可能不会按你预期的那样工作)。

对于简单的问题,通常很容易找到解决办法(如果你忘记了,试图用一个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调用任何修改方法后(特别是你不能仅仅这样做:

d['foo'].mutator()

然后期待修改“生效”,就像d是一个字典时那样)。

shelve确实有一个选项,可以将所有获取的项目缓存到内存中,但当然这会再次占用内存,并且在你最终关闭shelf对象时会导致长时间的延迟(因为所有缓存的项目必须保存回磁盘,以防它们修改过)。这个选项是我最初推动加入的(作为Python核心开发者),但我后来改变了主意,现在为加入这个选项感到抱歉(唉,至少它不是默认的!),因为应该使用它的情况很少,而且它常常会让不小心的用户陷入困境……抱歉。

顺便说一下,如果你不知道什么是修改方法,或者“可变方法”,它是指任何改变你调用它的对象状态的方法——例如,如果对象是列表,.append就是一个修改方法;如果对象是任何类型的容器,.pop也是如此。 当然,如果对象是不可变的(比如数字、字符串、元组、冻结集合等),就不需要担心,因为在这种情况下它没有可变方法;-)。

6

也许你应该使用数据库,不过可以看看 shelve 这个模块。

如果 shelve 不能满足你的需求,还有一个更强大的选择,就是 ZODB

撰写回答