如何在Python中从YAML文件创建树形数据结构?

时间:2018-11-04 11:20:11

标签: python python-3.x algorithm yaml

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

template:
 artifacts:
  config:
   a: value1
   b: value2
  jars:
   a: value1
   b: value2
  scripts:
   a: value1
   b: value2

我希望它像一棵树,如下所示:

template--
          |__artifacts__
                        |__config__
                        |          |__a__
                        |          |     |__value1
                        |          |
                        |          |__b__
                        |                |__value2
                        |__jars__ ...

我该怎么做?

1 个答案:

答案 0 :(得分:1)

有多个适用于Python的YAML解析器,但唯一 一个支持最新的YAML规范(2009年发布的1.2) 是ruamel.yaml(免责声明: 我是该软件包的作者)。其他软件包(PySyck,PyYAML) 也不支持加载有效的YAML构造,例如 序列/映射作为映射键。 ruamel.yaml可以定向到 为那些仅支持YAML 1.1的过时软件包转储YAML 1.1 版本的YAML规范。

嵌套的Python dict可以用作树结构,其键为a 节点的值和非dict叶节点的值。这是 从YAML文件中的映射加载的数据结构。

from pathlib import Path
from pprint import pprint
import ruamel.yaml

input = Path('input.yaml')
yaml = ruamel.yaml.YAML()
data = yaml.load(input)
pprint(data)

给出:

{'template': {'artifacts': {'config': {'a': 'value1',
                                       'b': 'value2'},
                            'jars': {'a': 'value1',
                                     'b': 'value2'},
                            'scripts': {'a': 'value1',
                                        'b': 'value2'}}}}

这看起来不像您的预期输出,字典也不是真正的树状结构。 当然,您可以遍历data-结构并创建Node s的树,但是 这有点落后,因为您可以告诉解析器直接创建一个Node 在建造树时。

import sys
from ruamel.yaml.constructor import SafeConstructor

class Node:
    # your node definition here
    pass


class MyConstructor(SafeConstructor):
    def construct_yaml_map(self, node):
        data = Node()
        yield data
        res = self.construct_mapping(node)
        # and update data with the parsed data

MyConstructor.add_constructor('tag:yaml.org,2002:map', 
                              MyConstructor.construct_yaml_map)


yaml = ruamel.yaml.YAML()
yaml.Constructor = MyConstructor
data = yaml.load(input)

请注意,以上内容会自动处理YAML文件中的递归结构, 当以正常方式加载YAML时,有些事情不容易实现。