在长时间运行的Python脚本中保持内存数据与文件同步

4 投票
5 回答
3139 浏览
提问于 2025-04-16 07:31

我有一个Python(2.7)脚本,它充当服务器,因此会长时间运行。这个脚本需要跟踪一些值,这些值会根据客户端的输入随时变化。

我希望能有一个东西,可以在内存中保存一个Python的数据结构(包含 dictlistunicodeintfloat 类型的值,也就是类似JSON的格式),让我可以随意更新这些值(除了不能多次引用任何引用类型的实例),同时还要能把这些数据保持在一个人类可读的文件中,这样即使突然断电,服务器也能重新启动并继续使用相同的数据。

我知道我说的基本上就是在谈论数据库,但我保存的数据非常简单,通常也不会超过1 kB,所以我在寻找一个尽可能简单的解决方案,能够提供我所描述的数据完整性。有没有好的Python(2.7)库可以让我做到这一点?

5 个回答

2

有没有什么特别的原因需要人类可读的格式呢?

我建议你可以看看sqlite,这是一种简单的数据库解决方案;或者使用pickle,这是一种简单的方法,可以把对象保存到磁盘上。不过这两种方式都不是特别容易让人看懂。

你提到的其他选择还有JSON或者XML。你可以使用内置的json模块来把对象转成JSON格式,然后把它写入磁盘。当你启动程序时,检查一下这个文件是否存在,如果存在就加载数据。

来自文档

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}
5

好吧,既然我们基本上是在讨论一个数据库,虽然是个很简单的数据库,你可能不会感到惊讶,我建议你看看 sqlite3 这个模块。

2

我同意你不需要一个复杂的数据库,因为看起来你只想要简单的文件写入。你需要把这个问题分成两部分来解决:序列化/反序列化和原子写入。

在第一部分,json或者pickle可能是适合你的格式。JSON的好处是人类可以读懂。不过,看起来这并不是你面临的主要问题。

一旦你把对象序列化成字符串,可以使用以下方法将文件原子性地写入磁盘,假设只有一个同时写入的程序(至少在POSIX系统上,下面会提到):

import os, platform
backup_filename = "output.back.json"
filename = "output.json"

serialised_str = json.dumps(...)
with open(backup_filename, 'wb') as f:
     f.write(serialised_str)
if platform.system() == 'Windows':
     os.unlink(filename)
os.rename(backup_filename, filename)

虽然os.rename可以覆盖已有的文件,并且在POSIX系统上是原子操作,但在Windows上情况就不一样了。在Windows上,os.unlink可能会成功,但os.rename可能会失败,这样的话你就只会有backup_filename而没有filename。如果你要在Windows上运行,就需要考虑这种可能性,在检查filename是否存在时要特别注意。

如果有可能有多个同时写入的程序,你就需要考虑使用同步机制。

撰写回答