Смешивание блоков и форматирование потока в YAML с Python

1

Я пытаюсь изменить значение, глубоко вложенное в файл YAML, используя Python и pyyaml. Мне нужно сохранить форматирование, которое представляет собой комбинацию блоков и потоков.

Я хочу изменить одно значение, вложенное в словарь, несколько слоев в глубине структуры. Например, я могу изменить значение x на 2:

a:
    b:
        c: {x:1, y:1}
        d: {r1: 2, r2: 4}
        e:
            f: 1
            g: 1

Я смог импортировать данные, изменить значение и выгрузить файл с форматированием блока или форматированием по умолчанию, но ни один из них не соответствует формату, который мне нужен. Есть ли способ смешать форматирование или изменить целевое значение без повторной записи всего файла?

  • 0
    Ваше значение для c вероятно, должно иметь пробелы после двоеточий ( {x: 1, y: 1} ). Я не уверен, что PyYAML анализирует это правильно. Должно ли это быть с PyYAML (т.е. вам нужна только поддержка устаревшего стандарта YAML 1.1)? Мой ruamel.yaml выполняет обход этого "из коробки", для чего нужно только указать 4 отступа для сопоставлений.
Теги:
yaml
pyyaml

1 ответ

0
Лучший ответ

Вероятно, вам стоит взглянуть за пределы PyYAML, одна из проблем заключается в том, что он строит ваши {x:1, y:1} в Python dict {"x": 1, "y": 1} где он должен быть создан для {"x:1": None, "y:1": None}, поскольку после двоеточия пробела нет, а скаляры не дублируются.

Предполагая, что вы хотите получить первое представление Python, даже если вы не измените свой YAML, чтобы быть правильным, и полагайтесь на ошибочную интерпретацию PyYAML, PyYAML не собирается выгружать это без дополнительного места после двоеточия, тем самым изменяя ваши файлы.

Я предлагаю вам посмотреть на ruamel.yaml (отказ от ответственности: я автор этого пакета), где вам только лишняя вещь, кроме исправления ввода YAML, заключается в том, чтобы установить отступ для сопоставлений в 4 (по умолчанию 2).

ruamel.yaml также поддерживает вложенные узлы стиля потока под блочным стилем, где PyYAML поддерживает только потоковый поток (по default-flow-style=True), all-block (default-flow-style=False) или all-block-with-collection -lele-nodes-flow (по умолчанию) из-за-коробки

import sys
import ruamel.yaml

yaml_str = """\
a:
    b:
        c: {x: 1, y: 1}  # these need spaces after the colon
        d: {r1: 2, r2: {r3: 3, r4: 4}}
        e:
            f: 1
            g: 1
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

который дает:

a:
    b:
        c: {x: 1, y: 1}  # these need spaces after the colon
        d: {r1: 2, r2: {r3: 3, r4: 4}}
        e:
            f: 1
            g: 1

И да, комментарий сохраняется.

  • 0
    Спасибо вам большое! Ваша посылка сделала именно то, что мне нужно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню