这是我为一个项目所做的。我有一些数据结构基本上是字典,其中包含一些对数据进行操作的方法。当我将它们保存到磁盘时,我将它们作为代码写入 .py 文件,当作为模块导入时,会将相同的数据加载到这样的数据结构中。
这合理吗?有什么大的缺点吗?我看到的好处是当我想对保存的数据进行操作时,我可以快速导入我需要的模块。此外,这些模块可以与应用程序的其余部分分开使用,因为您不需要单独的解析器或加载器功能。
这是我为一个项目所做的。我有一些数据结构基本上是字典,其中包含一些对数据进行操作的方法。当我将它们保存到磁盘时,我将它们作为代码写入 .py 文件,当作为模块导入时,会将相同的数据加载到这样的数据结构中。
这合理吗?有什么大的缺点吗?我看到的好处是当我想对保存的数据进行操作时,我可以快速导入我需要的模块。此外,这些模块可以与应用程序的其余部分分开使用,因为您不需要单独的解析器或加载器功能。
通过这种方式操作,您可能会获得一些便利,但您为此付出了多种代价。保存数据所需的空间以及保存和重新加载数据所需的时间大幅增加;并且您的安全风险是无限的——您必须严密地保护您重新加载模块的路径,因为它会为任何攻击者提供一个简单的途径来注入他们选择的代码以在您的用户 ID 下执行(pickle
本身并不是坚如磐石,安全方面,但是,与这种安排相比,它闪耀;-)。
总而言之,我更喜欢更简单和更传统的安排:可执行代码存在于一个模块中(在典型的代码加载路径上,一旦模块编译就不需要 R/W)——它只加载一次并且从已经编译的表格。数据以任何合适的格式存在于它们自己的文件(或数据库的一部分等)中,主要是标准格式(可能包括多语言格式,如 JSON、CSV、XML 等,如果我想保留的话)该选项打开以在将来轻松地从其他语言加载这些数据)。
最大的缺点是这是一个潜在的安全问题,因为很难保证文件不会包含任意代码,这可能非常糟糕。因此,如果您以外的其他人对文件具有写访问权限,请不要使用此方法。
一个合理的选择可能是使用Pickle模块,该模块专门用于将 python 结构保存和恢复到磁盘。
这是合理的,我一直这样做。显然,这不是您用来交换数据的格式,因此对于保存文件之类的东西来说,这不是一个好的格式。
但是例如,当我将网站迁移到 Plone 时,我经常会获取有关该网站的数据(例如应该迁移哪些页面的列表,或者应该如何将旧 url 映射到新 URL 的列表,或者标签列表)。这些通常以 Word och Excel 格式获得。此外,数据通常需要稍微处理一下,我最终得到了一个将一个 URL 映射到其他信息的字典。
当然,我可以将其保存为 CVS,并将其解析为字典。但相反,我通常将其保存为带有字典的 Python 文件。保存代码。
所以,是的,这是合理的,不,它不是您应该用于任何类型的保存文件的格式。然而,它通常用于跨越配置边界的数据,如上所示。
Alex Martelli 的回答绝对有见地,我同意他的观点。不过,我会更进一步,提出一个具体的建议:使用 JSON。
JSON 很简单,Python 的数据结构可以很好地映射到其中;并且有几个标准库和工具用于处理 JSON。Python 3.0 及更高版本中的json
模块基于simplejson,因此我将simplejson
在 Python 2.x 和json
Python 3.0 及更高版本中使用。
第二个选择是 XML。XML 更复杂,更难仅查看(或仅使用文本编辑器进行编辑),但有大量工具可以对其进行验证、过滤、编辑等。
此外,如果您的数据存储和检索需求变得非常重要,请考虑使用实际数据库。 SQLite很棒:它很小,对于小型数据库来说运行速度非常快,但它是一个真正的 SQL 数据库。我肯定会使用 Python ORM 而不是学习 SQL 来与数据库交互;我最喜欢 SQLite 的 ORM 是Autumn(小而简单),或者来自Django的 ORM (你甚至不需要学习如何在 SQL 中创建表!)然后,如果你长大了 SQLite,你可以升级到真正的PostgreSQL等数据库. 如果您发现自己编写了大量循环来搜索您保存的数据,特别是如果您需要强制执行依赖项(例如,如果删除 foo,也必须删除 bar),请考虑使用数据库。