将一个键的多个值存储在一个文件中,同时还能够将键和值附加到所述文件的最佳方法?

Best way to store multiple values of a key in a file, while also being able to append keys and values to said file?

我目前正在编写音板。为此,我需要存储用户给定的声音名称、路径和分配给它的热键。我还希望用户能够随时添加声音。

在 YAML 文档中,它看起来像这样:

sounds:
    sound1:
        path: ...
        name: ...
        hotkey: ...
    sound2:
        path: ...
        name: ...
        hotkey: ...

遗憾的是,我还没有找到一种简单的方法来将键(sound3、sound4...)附加到像这样的 yaml。 有没有一种简单的方法可以实现我的目标?

您将其加载到内存中,将其编辑为 python 数据结构,然后将其转储回 yaml 文件。

import yaml

with open("t.yaml") as f:
    data = yaml.load(f, Loader=yaml.SafeLoader)

data['sounds']['sound3'] = {'path': '...', 'name': '...', 'hotkey': '...'}

with open("t.yaml", "w") as f:
    yaml.dump(data, f)

虽然理论上可以追加到YAML文档,但实际上并不实用,但 最受控制的环境(可能导致换行的条目长度、数据结构、缩进等)。 如果您不向 root-level 序列添加元素或向 root-level 映射添加键,我会 甚至都没有开始尝试。

您应该做的是将文档加载到 Python 数据结构中,然后将整个结构转储回来。 如果您关心保留文档的格式、引用和评论,您可以这样做 这个使用:

import sys
from pathlib import Path
import ruamel.yaml

file_path = Path('sound.yaml')

new_sound = dict(path='/path/to/sound', name='sndname', hotkey='Alt+S')

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(file_path)
sounds = data['sounds']
idx = 0
while True:
    idx += 1
    if (key := f'sound{idx}') not in sounds:
        sounds[key] = new_sound
        break
yaml.dump(data, file_path)

print(file_path.read_text())

给出:

sounds:
    sound1:
        path: ..
        name: ..
        hotkey: ..
    sound2:
        path: ..
        name: ..
        hotkey: ..
    sound3:
        path: /path/to/sound
        name: sndname
        hotkey: Alt+S

以上搜索形式为 soundNNN 的第一个空闲键并将新数据插入结构中。如果输入在标量值周围有引号(即那些作为 Python 字符串加载的值),它们将被保留,就像 YAML 文档中的 EOL 注释一样。