ruamel.yaml:如何在顶层和其他元素内添加新元素

时间:2018-12-13 23:29:32

标签: python ruamel.yaml

ruamel.yaml文档稀疏,在这里我没有找到需要的答案。

my_file.yaml的内容:

desc: "blahblahblah"

问题1:如何(以编程方式)将“大小”作为元素添加到与“ desc”相同的级别(即树的TOP级别)

第二季度:如何(以编程方式)添加子元素深n倍

生成的文件应如下所示:

desc: 
    - "blahblahblah"
    - "desc_trans":
        - "Chinese": 
          - "Mandarin": "blahblahblah"
          - "Uyghur": "blahblahblah"
        - "Spanish": "blahblahblah"
size: "40k"

1 个答案:

答案 0 :(得分:1)

ruamel.yaml文档稀疏,但您尝试做的主要是 在Python级别上。您无需更改YAML,而是从文件中加载YAML 并将其解析为数据结构,更改该数据结构(使用 Python,因为ruamel.yaml是Python软件包),然后转储数据 回到YAML。

首先:由于缩进,您无法准确获得所需的内容 的序列不一致。 desc的值缩进为6, 其中的块顺序指示器(-)的偏移量 四岁。 "desc_trans"的值缩进为4,且缩进为 偏移量为2,"Chinese"的偏移量最小 二。 ruamel.yaml仅具有一对序列缩进和偏移量 值应用于所有(块)序列。

您要尝试实现一些棘手的事情:

  • 为键desc加载标量值并神奇地进行翻译 分成一个序列(旧的标量值是第一个 元件)。当然,代码仅应在以下情况下进行此更改

  • 具有普通标量和多余标量的组合 双引号。如果我正确看到它,那么任何不是 根级映射的键应双引号。你可以实现 以编程方式进行,但是在示例中,我将手动完成。

假设使用Python3:

from pathlib import Path
import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(Path('my_file.yaml'))

assert isinstance(data, dict)  # check that the root-level is a dictionary like object 
data['size'] = dq('40k')

if not isinstance(data['desc'], list):
    data['desc'] = [data['desc']]  # change the non-list into a list
l = data['desc']
# make the desc_trans dict first, cannot use dict(desc_trans=[dict(Chinese=[Mandarin=....
desc_trans = []
l.append({dq('desc_trans'): desc_trans})
Chinese = {dq('Chinese'): [{dq('Mandarin'): dq('blahblahblah')}]}
Spanish = {dq('Spanish'): dq('blahblahblah')}
desc_trans.append(Chinese)
desc_trans.append(Spanish)
# the next line also could be simplified using `desc_trans.append()`
data['desc'][1]['desc_trans'][0]['Chinese'].append({dq('Uygur'): dq('blahblahblah')})

# if you want to write to a file use: out = Path('output.yaml')
out = sys.stdout
yaml.dump(data, out)

给出:

desc:
  - "blahblahblah"
  - "desc_trans":
      - "Chinese":
          - "Mandarin": "blahblahblah"
          - "Uygur": "blahblahblah"
      - "Spanish": "blahblahblah"
size: "40k"

通常,我建议为变量分配一个深层元素,然后 为其添加或分配新密钥。

由于ruamel.yaml实际上将映射加载到有序字典子目录中, 并不一定需要具有这些单个键值序列 对映射,您具有"dest_trans""Chinese"。省略列表可简化代码,并且子类具有 .insert()方法可对键的顺序进行必要的控制。