Читать и выгружать [скобки, список] из и в yaml с python - PullRequest
2 голосов
/ 11 июня 2019

Я пытаюсь прочитать и вывести список в yaml, используя следующий код

with open(system_bsc_path) as f:
    system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
    yaml.safe_dump(system_bsc_dict, f)

Список ввода, как в файле:

chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
 [[16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
 [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]

правильно читается в python


Вывод, который сбрасывается:

chs_per_cath:
- - - 10
    - 11
    - 12
    - 13
  - - 13000
    - 13100
    - 13200
    - 13300
- - - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300
- - - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300

Как я могу получить тот же вывод, что и вход?

Ответы [ 3 ]

2 голосов
/ 11 июня 2019

Если вы хотите загрузить, а затем сбросить (возможно, после изменения некоторых значений), PyYAML не является подходящим инструментом, так как он будет манипулировать многими вещами в синтаксическом представлении.

Он будет отбрасывать стиль потока, как вы заметили, а также отбрасывать комментарии, имена якорей / псевдонимов, определенные целочисленные форматы (восьмеричные, шестнадцатеричные, двоичные) и т. Д.

Существует небольшой контроль надпоток-блочный стиль вывода в PyYAML.Вы можете иметь все-блок;наборы узлов как поток,
, и вы можете иметь весь поток, используя параметр default_flow_style для safe_dump().

Вам лучше использовать ruamel.yaml (отказ от ответственности: я являюсь автором этой библиотеки), так как она поддерживает ныне 10-летний стандарт YAML 1.2 (где PyYAML обрабатывает только устаревшие YAML 1.1) ивы получите вывод, который намного ближе и часто идентичен вводу YAML.

from ruamel.yaml import YAML

yaml = YAML()
with open(system_bsc_path) as f:
    system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
    yaml.dump(system_bsc_dict, f)

Если вы используете Python 3, вы можете использовать:

from pathlib import Path
yaml_file = Path(system_bsc_path)
system_bsc_dict = yaml.load(yaml_file)
yaml.dump(system_bsc_dict, yaml_file)

По умолчанию любой new списки (и dicts) будут в стиле блока, если вы хотите добавить список стиля потока, то вы можете использовать yaml.default_flow_style = True, чтобы установить все эти списки, или использовать точное управление, установив атрибут потока (.fa) на специальном внутреннем представлении:

def FSlist(l):  # concert list into flow-style (default is block style)
    from ruamel.yaml.comments import CommentedSeq
    cs = CommentedSeq(l)
    cs.fa.set_flow_style()
    return cs

system_bsc_dict['existing_field'] = FSlist(["Boston Maestro 4000"])
0 голосов
/ 11 июня 2019

Как уже упоминалось здесь , использование default_flow_style должно помочь.

Но, похоже, вам действительно нужно установить значение True.

Т.е.

>>> d = {'chs_per_cath': [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
  [[16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
   [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
  [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41],
   [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}

>>> print(yaml.dump(d, default_flow_style=True))
{chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]], [[16, 17, 18, 19,
        20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000,
        14100, 14200, 14300]], [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400,
        13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}
0 голосов
/ 11 июня 2019

Пожалуйста, посмотрите на default_flow_style аргумент для yaml.dump().

По умолчанию PyYAML выбирает стиль коллекции в зависимости от есть ли у него вложенные коллекции. Если коллекция вложена коллекции, ему будет присвоен стиль блока. В противном случае это будет иметь стиль потока.

Если вы хотите, чтобы коллекции всегда сериализовались в стиле блока, установите для параметра default_flow_style для dump () значение False.

https://pyyaml.org/wiki/PyYAMLDocumentation#DumpingYAML

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