将YAML文件拆分为两个单独的文件

时间:2016-11-09 10:13:01

标签: python yaml

我试图将YAML文件拆分为两个不同的文件,如下所示:

def yaml_loader():
  try:
    with open("test.yaml", "r") as stream:
       data = yaml.load(stream)
       for workload in data:
         with open(workload['workload']['name'] + '.yaml', 'a') as outfile:
              yaml.dump(workload, outfile)
  except yaml.YAMLError as out:
    print(out)

YAML:

- workload:
     name: c1
     param:
       p1: 1
       p2: 2

- workload:
    name: c2
    param:
      p1: 30
      p2: 200

但是在输出中,对于YAML语法,两个文件都缺少-

workload:
   name: c1
   param:
     p1: 1
     p2: 2

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

@Ignacio Vazquez-Abrams说:

def yaml_loader():
  try:
    with open("test.yaml", "r") as stream:
       data = yaml.load(stream)
       for workload in data:
         with open(workload['workload']['name'] + '.yaml', 'a') as outfile:
              # if you put the variable "workload" in a list, you get the '-' in the yaml, as it denotes a list item.
              yaml.dump([workload], outfile)
  except yaml.YAMLError as out:
    print(out)

in a yaml,

" - item:" 表示列表项,因此如果不将输出放在列表中,您将无法获得" - "

答案 1 :(得分:0)

您的代码未按预期运行,但也未按您的说明运行。

在第一次运行时,您将在c1.yaml中获得此输出:

workload:
  name: c1
  param: {p1: 1, p2: 2}

因为默认情况下load()dump()(在ruamel.yaml和PyYAML中)将默认为不包含其他集合元素的集合元素(映射,序列)上的流样式。

此外,如果您第二次调用该例程,c1.yaml文件将包含:

workload:
  name: c1
  param: {p1: 1, p2: 2}
workload:
  name: c1
  param: {p1: 1, p2: 2}

因为你打开追加。

如果您无法控制文件来源并且可能包含YAML标记,则使用load()进行此类拆分文件可能也不是一个好主意。

上述问题是在缺失的顶层序列元素之上,可以很容易地解决,如@Ignacio Vazquez-Abrams所示。

也没有必要将for语句放在第一个with语句中,从而延迟关闭输入文件。 data不是迭代器。

我建议使用ruamel.yaml¹往返加载/转储来做到这一点。除了保留块resp。流式,它还支持YAML 1.2,保留您的注释,保留映射键的顺序,并可以在源中保留标量字符串的引号:

import ruamel.yaml as yaml

def yaml_loader():
    try:
        with open("test.yaml", "r") as stream:
            data = yaml.round_trip_load(stream, preserve_quotes=True)
        for workload in data:
            with open(workload['workload']['name'] + '.yaml', 'w') as outfile:
                yaml.round_trip_dump([workload], outfile)
    except yaml.YAMLError as out:
        print(out)

yaml_loader()

会给你:

- workload:
    name: c1
    param:
      p1: 1
      p2: 2

¹这是使用ruamel.yaml完成的,我是作者。