动态构建 YAML 对象

Constructing a YAML object dynamically

我正在使用 PyYAML 库动态生成 YAML 文件。

例如,

import yaml

with open(r'content.txt', 'r') as a_file:


  with open(r'file.yaml', 'a') as file:

    file.write("  root:")
    file.write("\n")
       
  for line in a_file:
    
    stripped_line = line.strip()
    txt = stripped_line
    x = txt.split("=")
    
    with open(r'file.yaml', 'a') as file:
       yaml.dump([{'child-1':x[0],'child-2':x[1]}])

content.txt 文件可能包含以下形式的数据:

a=b
c=d

所需的最终 YAML 文件应如下所示:

  root:
  - child-1: a
    child-2: b

  - child-1: c
    child-2: d

请注意根对象的缩进,假设它嵌套到另一个根对象中

但是上面的代码使得输出为:

  root:
-   child-1: a
    child-2: b

-   child-1: c
    child-2: d

这不是有效的 YAML。 在 yaml.dump() 命令中提及根对象会复制它:

#for line in content.txt
#yaml.dump({'root':[{'child-1': x[0], 'child-2':x[1]}])

  root:
  - child-1: a
    child-2: b
  root
  - child-1: c
    child-2: d

由于python yaml.dump() 函数要求我们将对象与根对象及其子对象一起完整提及,因此似乎很难将这两个对象分开处理。

有没有办法分开调用这些对象和以后 append/link 根子对象?

您没有使用 PyYAML 写入 YAML 文档,因为您忘记向 dump() 提供流参数,不幸的是,它在 PyYAML 中是可选的,因为您没有使用它的结果(字符串)值,可替换为pass.

除此之外,您应该一次性将 YAML 文档写入流,而不是尝试附加到它 ('a')。因此,立即创建并转储您想要的整个数据结构:

import sys


import yaml   

children = []
data = dict(root=children)

with open('content.txt', 'r') as a_file:
    for line in a_file:
        x = line.strip().split('=')
        children.append({'child-1': x[0], 'child-2': x[1]})

with open('file.yaml', 'w') as o_file:
    yaml.dump(data, o_file)

with open('file.yaml', 'r') as i_file:
     print(i_file.read(), end='')

给出:

root:
- child-1: a
  child-2: b
- child-1: c
  child-2: d

您还应注意 PyYAML 仅支持 YAML 1.1 版,尽管 最新版本是 YAML 1.2,所以你可能想切换到 ruamel.yaml 支持此标准的库(已有 10 多年历史。免责声明我是 ruamel.yaml 的开发者)。 为了做到这一点替换

import yaml

 import ruamel.yaml
 yaml = ruamel.yaml.YAML(type='safe')

这对于大文件也更快。