如何在Python中实现一个持久化计数器

3

有没有一种方法可以在Python中拥有“最后已知”计数器,即使在服务器重启后也能存活?

我有一个Python脚本,按计划(由cron)启动。它以预定义格式读取文档ID的文件。我需要记住上次处理的文档ID,以便忽略所有之前的ID。


1
将其保存在数据库/文件中? - Ben
我宁愿不安装Oracle,只为了保存一个计数器 :) 寻找一种轻量级的解决方案 :) - Anthony
关于文件,那是个好主意,但不跨平台。 - Anthony
4
什么?将文件保存不是跨平台的吗?怎么回事? - Chris Morgan
2
@Antonio:无论你安排什么,你都需要在某个地方访问可写位置。 - Chris Morgan
显示剩余3条评论
2个回答

5
任何需要在重启后仍然存在的值都需要放入持久性存储中,即磁盘。这意味着需要某种类型的文件,无论是简单的纯文本文件还是数据库文件都可以。您在评论中表示您不认为这是“跨平台”的,但如果没有某种类型的文件系统支持,那么它将成为一个奇怪的平台。
如果您需要结构化存储,则 Python 的 sqlite3 模块内置了 SQLite 支持。但是,看起来您只需要存储一个单一的 ID,因此一个简单的文件就足够了。我建议使用以下内容:
import os

DATA_FILENAME = os.path.expanduser("~/document-counter.txt")

def update_document_id(new_id):
    with open(DATA_FILENAME, "w") as fd:
        fd.write(new_id + "\n")

def retrieve_document_id():
    with open(DATA_FILENAME, "r") as fd:
        return fd.readline().strip()

你可能需要更好的错误检查(例如,捕获如果文件不存在时抛出的异常等)。但这让你了解了解决方案可以多么简单。最好捕获异常(EAFP经常被认为比LBYL更符合Python风格),但如果你想显式检查文件是否存在,那么也可以以一种可移植的方式轻松实现:

if not os.path.exists(DATA_FILENAME):
    print "No file found. Deal with it."

如果您需要在以后添加更多的数据字段,我建议使用SQLite - 它方便、强大,并且允许您与其他语言的应用程序进行互操作,如果将来需要的话。此外,如果需要,您可以使用独立的SQLite命令行客户端来操作数据。您只需向sqlite3.connect()方法提供一个文件名,因此它基本上就像打开一个文件一样容易,只是您可以随后把SQL语句传递给它。
然而,对于简单的单个ID,我建议仍然使用纯文本文件 - 您真的不需要比这更兼容的了。

我认为使用标准库中的“shelve”模块会更简单。 - Chris Morgan
是的,在像这样简单的情况下,shelve 没有任何问题。就我个人而言,我更喜欢纯文本文件或 SQLite 文件,因为它们在其他语言中更容易支持,但我完全理解 OP 没有将其指定为要求。他对跨平台解决方案的关注使我想到,也许跨语言的解决方案可能会吸引他。对于结构化数据,shelve 肯定比自己编写纯文本格式更好 - 当然,除非我需要存储 Python 类或类似对象(那么 shelve 更好)。 - Cartroo
很可能已经存在其他持久性数据需求或将出现。一个适当的数据库肯定是个明智的选择。像ConfigParser这样的东西比shelve更容易跨语言。 - Chris Morgan

1

将其存储在数据库或文件中。您可以选择将其写入文件; 您可以选择使用ConfigParsercsv; 或者您可以选择使用shelve(它非常简单易用;如果这是您想要的所有持久性存储,那么它可能是最直接的)。还有其他选项,请查看标准库提供的内容以了解其中的感觉。您仍需要指定要存储结果的文件,并且权限需要适当,但这不应该很难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接