使用Python从YAML文件转储数据

时间:2016-11-02 13:10:13

标签: python parsing yaml

我有一个YAML文件,如下所示:

- workload:
    name: cloud1
    param:
      p1: v1
      p2: v2

- workload:
    name: cloud2
    param:
      p1: v1
      p2: v2

我可以使用以下Python脚本解析文件:

#!/usr/bin/env python

import yaml   

try:
 for key, value in yaml.load(open('workload.yaml'))['workload'].iteritems():
   print key, value
except yaml.YAMLError as out:
  print(out)

输出:

name cloud1
param {'p1': 'v1'}

但我正在寻找的是:

workload1 = cloud1
workload1_param_p1 = v1
workload1_param_p2 = v2

workload2 = cloud2
workload2_param_p1 = v1
workload2_param_p2 = v2

1 个答案:

答案 0 :(得分:1)

您的输出与输入不匹配,因为YAML文件的顶层是映射到Python list的序列。
另一件事并不完全清楚,workload,尤其是1中的workload1来自哪里。在下文中,我假设它们来自构成序列元素的映射的关键字。该序列元素的位置(从1开始,因此idx+1)。 name从值的副本中弹出,以便可以递归地正确地转储其余部分:

import sys
import ruamel.yaml

yaml_str = """\
- workload:
    name: cloud1
    param:
      p1: v1
      p2: v2

- workload:
    name: cloud2
    param:
      p1: v1
      p2: v2
"""

data = ruamel.yaml.round_trip_load(yaml_str)

def dump(prefix, d, out):
    if isinstance(d, dict):
        for k in d:
            dump(prefix[:] + [k], d[k], out)
    else:
        print('_'.join(prefix), '=', d, file=out)

for idx, workload in enumerate(data):
    for workload_key in workload:
        values = workload[workload_key].copy()
        # alternatively extract from values['name']
        workload_name = '{}{}'.format(workload_key, idx+1)
        print(workload_name, '=', values.pop('name'))
        dump([workload_name], values, sys.stdout)
    print()

给出:

workload1 = cloud1
workload1_param_p1 = v1
workload1_param_p2 = v2

workload2 = cloud2
workload2_param_p1 = v1
workload2_param_p2 = v2

这是使用ruamel.yaml完成的,这是一个YAML 1.2解析器,我是作者。如果你只有YAML 1.1代码(由PyYAML支持),你仍然应该使用ruamel.yaml,因为它的round_trip_loader保证在workload_param_p1之前打印workload_param_p2(不保证PyYAML)。