在python中简单数据存储的最佳格式



作为一个相对较新的程序员,我多次遇到这样的情况:从外部源读取和组装程序数据而不是将其编写在代码中对我有益。当存在大量相同类型的对象时,通常就是这种情况。在这种情况下,对象定义会很快占用代码中的大量空间,并给可读性增加不必要的障碍。

举个例子,我一直在开发基于文本的RPG,它有大量的房间和物品需要跟踪。即使是一些物品和房间也会导致大量的对象创建代码块。

我认为在这种情况下使用某种格式的外部数据存储,从文件中读取会更容易。在这样的文件中,项目和房间将按名称和属性存储,以便它们可以相对轻松地解析为对象。

什么格式最适合此?我觉得像 SQL 这样的成熟数据库会给一个相当轻的脚本增加不必要的膨胀。另一方面,通过外部应用程序或其他 python 脚本编辑此数据的简单方法很重要。在较轻松的一端,我听到最常提到的几个是XML,JSON和YAML。

据我所知,XML 似乎不是最佳选择,因为许多人似乎发现它很复杂且难以有效使用。

JSON 和 YAML 似乎都可以工作,但我不知道在外部编辑它们有多容易。在这种情况下,速度不是主要问题。虽然更快的实现当然是可取的,但它并不是我可以使用的限制因素。

在这里和通过谷歌环顾四周,虽然我已经看到了很多关于这个话题的信息,但我无法找到任何对我特别有帮助的东西。像JSON或YAML这样的格式是否足以做到这一点,或者我最好有一个成熟的数据库?

虽然这里已经有很好的答案,但我只是推荐JSON用于您的目的,唯一的原因是,由于您是新程序员,因此阅读和翻译起来最直接,因为它具有与本机Python数据类型(列表[]和字典{})的最直接映射。 可读性有很长的路要走,是Python编程的原则之一。

我是使用 Python Pickles 将数据存储在文件中的忠实粉丝。

Pickle可以正确地序列化任何类型的Python对象,特别是"复杂"的东西 - 任何类型的Python类,函数 - 任何类型的对象!

它不仅限于相对简单的结构,如"列表"、"字典"、"字符串"和"数字",以 JSON 等数据格式提供。

这取决于您的用例。

如果您的文件相对较小且几乎是静态的,则 YAML 或 JSON 都可以达到目的。查看 YAML 和 JSON 有什么区别?何时选择其中一个以获取更多信息

如果你的文件很大,或者动态的,或者会涉及一些并发控制,那么你最好让数据库来处理它。

我对几个应用程序有类似的需求,并使用 jsonpickle 选择了 JSON。

为了使 json 输出更具人类可读性/可编辑性,我使用以下格式设置:

jsonpickle.set_encoder_options('simplejson', sort_keys=True, indent=4)

然后对数据进行编码/解码:

text = jsonpickle.encode(data)
...
data = jsonpickle.decode(text)

jsonpickle的好处是它允许您存储类对象,而无需手动将所有内容转换为字典(就像使用纯JSON一样)。 Jsonpickle 还包括钩子,让您定义自己的转换器,如果您需要更好地控制转换方式。

关系数据库当然有其一席之地,特别是对于大型多人游戏;如果你的很多游戏逻辑涉及对大量对象的频繁小更新,数据库方法将获胜。

[更新]进一步说明,如果您要手动编辑大量 json 文件,请为自己制作一个小的 json 检查器脚本,您可以在编辑的文件上运行以查找语法错误,这将为您节省相当多的时间。

如果需要可编辑性,YAML 是您命名的选项中的最佳选择,因为它没有 <> 或 {} 必需的分隔符。

XML,JSON或YAML是比关系数据库给你的更"松散"的格式。关系数据库是面向表的,会对存储数据的方式施加一些约束。

从你的描述来看,我会坚持使用JSON或YAML。有了它们,你可以表达相当复杂的对象图(如果你需要更"正式"的类型或模式,XML将是我的选择)。

对于读取或写入操作,通常考虑序列化/反序列化对象/从对象序列化/反序列化(如 http://docs.python.org/library/json.html)。

我很想研究一些可以输出带有注释的图形可视化(DOT 格式)的 GUI,这样您就可以创建房间和它们之间的链接(一种图形)。然后,您可能需要另一种格式来支持更重的信息。

但是应该可以轻松创建地图,房间之间的链接(包含物品或陷阱等),并且您可以使用公共库在png或其他东西中生成地图的图形。

只是我脑海中的随机想法 - 随意忽略!

对于小型封闭的回声系统,泡菜是一个很好的解决方案。 根据我的经验和Ilia Zaitsev的文章,一个更强大,更快,更轻便的文件,我建议将pandas DataFrame用于关系数据结构和pyarrow.father用于读/写的组合。

例如:

import pandas as pd
from dataclasses import make_dataclass
import pyarrow.feather as feather
Point = make_dataclass("Point", [('tag', str), ('x', float), ('y', float)])
df = pd.DataFrame([Point('tl', 1.0, 1.0), Point('br', 3.0, 4.0)])
feather.write_feather(df, '/tmp/point_data.arrow)

最新更新