python yaml 格式 - 保留新行和缩进

问题描述 投票:0回答:1

我正在尝试读取结构化 YAML 文件,并在更新一些条目后将其写回另一个文件(键和值都可能会被修改)。

但是,我特别想保留文件的换行符和原始结构。

输出文件必须:

  1. 维护键和值的顺序或元素
  2. 保留列表的新行(即每个元素必须从新行开始)
  3. 部分列表不应换行 - 例如示例文件中的“
    description
    ”和“
    nicknames

目前我使用

ruamel
来处理数据,如下所示:

from ruamel.yaml import YAML

yaml = YAML()
yaml.preserve_quotes = True

with open('inputfile.yaml', 'r') as f1:
    data = yaml.load(f1)

with open('outputfile.yaml', 'w') as f2:
    yaml.dump(data, f1)

假设我有这个

inputfile.yaml

- { "fruits_basket": [
  { "name": "Strawberry",
    "type": "fruit",
    "custom_labels": [
        { "x": "cereal", "a_value": "delicious"},
        { "b": "factory", "b_value": ["Vitamin C", "Manganese"]},
        { "c.d": "origin", "a_value": "Canada"},
        { "description": 
            [
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "small"},
                ],
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "custom"},
                ]
            ]
        }
    ]
  },
  { "name": "banana",
    "type": "fruit",
    "custom_labels": [
        { "x": "cerial", "a_value": "delicious"},
        { "b": "factory", "b_value": ["Vitamin B6", "Magnezium"]},
        { "c.d": "origin", "a_value": "Canada"},
        { "description": 
            [
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "big"},
                ],
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "custom"},
                ]
            ]
        }
    ]
  },
]
}


- { "smaller": [
  { "field": "six1",
    "header" : "strings",
    # Some comment descriptor
    "body": "formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["a", "b", "c"]},
      { "avatars": "a_list", "nicknames": 
        [
          ["a", "b", "c"],
          ["bruno", "mars", "rocks", "and", "this", "is", "a", "very", "long", "list", "not", "considering", "maximun", "width"]
        ]
      },
      { "number_of_players", "10"}
    ]
  },
  { "field": "citrus",
    "header" : "strings",
    # Some comment descriptor
    "body": "pre-formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["d", "a", "b"]},
      { "avatars": "a_list", "nicknames": 
        [
          ["c", "a", "b"],
          ["gotta", "take", "it", "to", "the", "other", "side","think", "of", "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua"]
        ]
      },
      { "number_of_players", "15"}
    ]
  },
  { "field": "zeta",
    "header" : "cars",
    # Some comment descriptor
    "body": "pre-formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["z", "j", "l", "k"]},
      { "avatars": "a_list", "nicknames": 
        [ 
          ["z", "j", "l", "k"],
          ["gotta", "take", "it", "to", "the", "other", "side", "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua"]
        ]
      },
      { "number_of_players", "20"}
    ]
  },
]
}

我希望得到的

outputfile.yaml
是:

- { "fruits_basket": [
  { "name": "Strawberry",
    "type": "fruit",
    "custom_labels": [
        { "x": "cereal", "a_value": "delicious"},
        { "b": "factory", "b_value": ["Vitamin C", "Manganese"]},
        { "c.d": "origin", "a_value": "Canada"},
        { "description": 
            [
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "small"},
                ],
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "custom"},
                ]
            ]
        }
    ]
  },
  { "name": "banana",
    "type": "fruit",
    "custom_labels": [
        { "x": "cerial", "a_value": "delicious"},
        { "b": "factory", "b_value": ["Vitamin B6", "Magnezium"]},
        { "c.d": "origin", "a_value": "Africa"},
        { "description": 
            [
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "big"},
                ],
                [
                    { "notice1": "warning", "attribute": "multiple"},
                    { "notice2": "info", "attribute": "custom"},
                ]
            ]
        }
    ]
  },
]
}


- { "smaller": [
  { "field": "six1",
    "header" : "strings",
    # Some comment descriptor
    "body": "formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["a", "b", "c"]},
      { "avatars": "a_list", "nicknames": 
        [
          ["a", "b", "c"],
          ["bruno", "mars", "rocks", "and", "this", "is", "a", "very", "long", "list", "not", "considering", "maximun", "width"]
        ]
      },
      { "number_of_players", "22"}
    ]
  },
  { "field": "citrus",
    "header" : "strings",
    # Some comment descriptor
    "body": "pre-formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["d", "a", "b"]},
      { "avatars": "a_list", "nicknames": 
        [
          ["c", "a", "b"],
          ["gotta", "take", "it", "to", "the", "other", "side","think", "of", "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua"]
        ]
      },
      { "number_of_players", "15"}
    ]
  },
  { "field": "zeta",
    "header" : "cars",
    # Some comment descriptor
    "body": "pre-formatted",
    "more_lists": [
      { "proportions":"large", "costruction_list": ["z", "j", "l", "k"]},
      { "avatars": "a_list", "nicknames": 
        [ 
          ["z", "j", "l", "k", "a", "b", "c"],
          ["gotta", "take", "it", "to", "the", "other", "side", "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua"]
        ]
      },
      { "number_of_players", "20"}
    ]
  },
]
}

我已经检查了

ruamel
文档

以及一些 Stack Overflow 问题,例如

我尝试了

ruamel
的多个配置选项,例如:

yaml.preserve_quotes = True
yaml.compact(seq_seq=True, seq_map=True)
yaml.indent(mapping=6, sequence=4, offset=0)
yaml.width = 2048

以及

typ
自卸车的不同
ruamel
值,例如:

yaml = YAML(typ="safe")
yaml = YAML(typ="unsafe")
yaml = YAML(typ="full")
yaml = YAML(pure=True)

但是,无论我如何尝试,我似乎都无法保留原始文件的换行符和结构。

我怎样才能做到这一点?

python configuration yaml config ruamel.yaml
1个回答
0
投票

IIRC ruamel.yaml 上的文档指出它试图保留 block 结构化 YAML。目前不保留流样式映射和序列中的注释(虚假换行符存储为注释)。

这并不是因为无法保存这些,而是需要额外的工作,因为附加评论信息的机制主要是基于前面的关键c.q。元素索引,并且没有对流程样式映射/序列指示器执行此操作的规定。

© www.soinside.com 2019 - 2024. All rights reserved.