我正在尝试读取结构化 YAML 文件,并在更新一些条目后将其写回另一个文件(键和值都可能会被修改)。
但是,我特别想保留文件的换行符和原始结构。
输出文件必须:
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)
但是,无论我如何尝试,我似乎都无法保留原始文件的换行符和结构。
我怎样才能做到这一点?
IIRC ruamel.yaml 上的文档指出它试图保留 block 结构化 YAML。目前不保留流样式映射和序列中的注释(虚假换行符存储为注释)。
这并不是因为无法保存这些,而是需要额外的工作,因为附加评论信息的机制主要是基于前面的关键c.q。元素索引,并且没有对流程样式映射/序列指示器执行此操作的规定。