Как я могу создать древовидную структуру данных из файла YAML в Python? - PullRequest
0 голосов
/ 04 ноября 2018

Предположим, у меня есть файл 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 голосов
/ 04 ноября 2018

Для Python доступно несколько парсеров для YAML, но только один, поддерживающий последнюю спецификацию YAML (1.2, выпущенный в 2009 году) is ruamel.yaml (отказ от ответственности: Я автор этого пакета). Другие пакеты (PySyck, PyYAML) также не поддерживают загрузку допустимых конструкций YAML, таких как последовательности / отображения в качестве ключей отображения. ruamel.yaml может быть направлено на дамп YAML 1.1 для тех устаревших пакетов, которые поддерживают только версия спецификации YAML.

Вложенный питон dict s может использоваться как древовидная структура с ключами значение узла и значения, которые не являются dict s конечными узлами. Это структура данных, загружаемая из сопоставлений в файле 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, загруженному обычным способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...