Как определить стиль нового словаря в ruamel yaml? - PullRequest
2 голосов
/ 28 мая 2020

В качестве вопроса Есть ли способ сохранить порядок при двустороннем сбросе YAML в Python? решен, структуры данных импортируются правильно, атрибуты стиля установлены правильно, et c. Я написал код для вставки вложенного словаря CommentedMap () (sw-99-54321), который содержит несколько словарей и списков, например:

  dc01:
    sw-06-50001:  # existing entry
      servers:
      - {ip: 10.255.206.12, port: 50001, weight: 100}
      - {ip: 10.255.206.13, port: 50001, weight: 90}
      virtual: {ip: 192.168.1.4, port: 50001}

    sw-99-54321:  # the entry I am trying to add   
      servers:
      - ip: 192.168.1.1
        port: '65535'
        weight: 100
      - ip: 192.168.1.2
        port: '65534'
        weight: 90
      virtual:
        ip: 192.168.1.1
        port: 65532

Я хочу отформатировать sw-99-54321 "таким же образом, как существовал" sw-06-50001.

Я знаю, что стиль привязан к атрибуту <var>.fa.__flow_style, но я не могу изменить его напрямую:

data['services']['dc01']['sw-99-54321']['servers'].fa.set_flow_style='True'
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'Format' object attribute 'set_flow_style' is read-only 

Есть ли способ установить его или определить стиль блока для некоторых элементов другим способом?

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Наконец, data['services']['dc01']['sw-99-54321']['servers'].fa.set_block_style() выполнил форматирование, которое я хотел. А data['services']['dc01']['sw-99-54321']['servers'].fa.set_flow_style() делает обратное.

0 голосов
/ 28 мая 2020

Поскольку в вашем примере есть стиль потока, вы можете сделать две вещи

1) Явно установить стиль потока:

import sys
import ruamel.yaml

yaml_str = """\
dc01:
  sw-06-50001:  #existed entry
    servers:
    - {ip: 10.255.206.12, port: 50001, weight: 100}
    - {ip: 10.255.206.13, port: 50001, weight: 90}
    virtual: {ip: 192.168.1.4, port: 50001}
"""

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
data['dc01']['sw-99-54321'] = n = {}
n['servers'] = l = []
l.append(ruamel.yaml.comments.CommentedMap([('ip', '192.168.1.1'), ('port', '65535'), ('weight', 100)]))
l[-1].fa.set_flow_style()
l.append(ruamel.yaml.comments.CommentedMap([('ip', '192.168.1.2'), ('port', '65534'), ('weight', 90)]))
l[-1].fa.set_flow_style()
n['virtual'] = x = ruamel.yaml.comments.CommentedMap([('ip', '192.168.1.1'), ('port', '65532')])
x.fa.set_flow_style()

yaml.dump(data, sys.stdout)

, что дает:

dc01:
  sw-06-50001:  #existed entry
    servers:
    - {ip: 10.255.206.12, port: 50001, weight: 100}
    - {ip: 10.255.206.13, port: 50001, weight: 90}
    virtual: {ip: 192.168.1.4, port: 50001}
  sw-99-54321:
    servers:
    - {ip: 192.168.1.1, port: '65535', weight: 100}
    - {ip: 192.168.1.2, port: '65534', weight: 90}
    virtual: {ip: 192.168.1.1, port: '65532'}

2) Установите для всех листовых узлов глобальный стиль потока:

import sys
import ruamel.yaml

yaml_str = """\
dc01:
  sw-06-50001:  #existed entry
    servers:
    - {ip: 10.255.206.12, port: 50001, weight: 100}
    - {ip: 10.255.206.13, port: 50001, weight: 90}
    virtual: {ip: 192.168.1.4, port: 50001}
"""

yaml = ruamel.yaml.YAML()
yaml.default_flow_style = None

data = yaml.load(yaml_str)
data['dc01']['sw-99-54321'] = n = ruamel.yaml.comments.CommentedMap()
n['servers'] = l = []
l.append(ruamel.yaml.comments.CommentedMap([('ip', '192.168.1.1'), ('port', '65535'), ('weight', 100)]))
l.append(dict(ip='192.168.1.2', port='65534', weight=90))
n['virtual'] = ruamel.yaml.comments.CommentedMap([('ip', '192.168.1.1'), ('port', '65532')])

yaml.dump(data, sys.stdout)

, что дает:

dc01:
  sw-06-50001:  #existed entry
    servers:
    - {ip: 10.255.206.12, port: 50001, weight: 100}
    - {ip: 10.255.206.13, port: 50001, weight: 90}
    virtual: {ip: 192.168.1.4, port: 50001}
  sw-99-54321:
    servers:
    - {ip: 192.168.1.1, port: '65535', weight: 100}
    - {ip: 192.168.1.2, port: '65534', weight: 90}
    virtual: {ip: 192.168.1.1, port: '65532'}

с помощью этого метода нет необходимости создавать CommentedMap() экземпляров, вы можете использовать обычные dicts

...