我不喜欢“yaml.dump()”保存文件的方式,有替代方案吗?

1 投票
2 回答
1370 浏览
提问于 2025-04-16 14:53

我最近发现了YAML,这种格式对我的项目(我正在创建一个基于文本的角色扮演游戏)来说非常棒。它完美地处理了我需要的所有内容——区域文件(房间描述、出口、物品、NPC等)、脚本文件、NPC文件、物品文件……统统都能搞定!不过,有一件事让我头疼……

当我需要更新这些文件里的值时,当然得把它们写回硬盘,以保持更改。可惜YAML的dump()方法真是让人抓狂。首先,它会把所有的键按字母顺序排列,然后每一对键值(k:v)都放在单独的一行上。这就导致一个原本只有5行的文件变成了94行。

我试着用write()把YAML对象写回硬盘,但结果却报了个错:

TypeError: expected a character buffer object

这个错误让我很困惑。虽然用Pickle可以保存数据,但我觉得这样会破坏YAML的特性。有没有什么好的方法可以在不使用dump()的情况下保存YAML对象?我听说过SQLite,这个东西能像YAML一样工作吗?我对数据库几乎没有经验,但感觉YAML对象基本上就像数据库。要是为了使用SQLite重写所有代码,值得吗?用SQLite保存更改的值会不会比我现在遇到的问题简单多了?

如果能提供一些帮助就太好了。我真的很喜欢YAML。我花了很长时间才找到一种存储我游戏所需数据的方法,当我发现YAML时,就像它散发着神圣的光芒,天使们在为它歌唱——所以你能理解我为什么想先知道有没有办法在不使用dump()的情况下把YAML数据保存到硬盘。如果没有,任何建议我都非常感激!

2 个回答

0

用YAML和Python可以保持数据的顺序。

Python有一个叫OrderedDict的东西,而YAML也有一个类似的有序映射,叫做omap

不过,当你用YAML把OrderedDict导出时,它会试图保留OrderedDict的Python对象类型,而不是把它转换成YAML的omap。这部分是因为YAML的规范是为了兼容很多编程语言,而且我认为YAML的映射或omap允许重复的键(我得再查一下,但我见过有人提到这是YAML和JSON之间的一个“关键”区别——YAML说明了它如何处理重复的键,而JSON则没有)。

不过,有办法让YAML把数据加载到OrderedDict中,并把OrderedDict按顺序导出到一个映射或omap中。我找到的最简洁的来源是py-lessly。虽然网上还有其他实现。我也喜欢py-lessly的代码,它导出的YAML映射很简单,不需要在每个字典旁边加上!!omap,这样YAML看起来更整洁!

还有一个layered-yaml-attrdict-config,它把YAML数据加载到一个叫AttrDict的OrderedDict子类中,并增加了一些额外的功能。我需要在这个实现上加一些东西才能适应我的需求——我觉得它在导出时丢失了顺序,所以我从py-lessly的实现中添加了一些代码。我还想处理结合字典和列表结构的情况,因此需要写一些额外的代码来递归地将AttrDict应用到整个数据结构上。

通过这些例子,你可以看到如何使用YAML来处理有序映射。我目前正在为应用程序设置实现这个功能,希望它能保持相对易读,并且顺序也很重要。

1

YAML是一种在Python和可以用文本编辑的格式之间转换字典和列表的方式。它并不适合用来存储复杂的数据、多人同时访问、快速查找数据、保证数据完整性等,这些都是数据库的特点。

你把YAML当成数据库来用,但它其实不是数据库。举个例子,键的顺序变化是因为key: value这种形式是用Python字典表示的,而字典本身是没有顺序的。

你确实需要花点时间学习一下数据库的基础知识。

SQLite是一个很好的入门选择。你也可以看看Postgres或MySQL。你可能还想找一些关于SQL和用Python访问数据库的初学者指南,网上有很多这样的资源。

撰写回答