python-3.x - 使用嵌入式 JSON 加载 YAML 时格式不正确(无换行符)
问题描述
我正在尝试解析文件中的 YAML 输入:
root: {
children : { key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}
}
我正在使用 ruamel.yaml,使加载的代码部分配置为保留引号,然后我手动添加一个新条目:
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 4096
yaml.indent(sequence=4, offset=2)
with open(yml_file, 'r') as file:
print("Modifying file: '%s'..." % str(file))
data = yaml.load(file)
data['root'][new_project_name.lower()] = {'key': "%s" % new_project_name.lower(),
'test_version': "{{ %s_version | default(\'1.0.0-SNAPSHOT\') }}"
% new_project_name.lower()}
with open(yml_file, 'w') as file:
yaml.dump(data, file)
问题是,当使用新条目写入文件时,我将所有内容都放在同一行中,因此似乎没有保留新行(CR LF),(它似乎甚至在没有它们的情况下加载它)你知道有没有办法保存它们?
输出是(同一行中的所有内容):
root: {children : { key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}}
解决方案
ruamel.yaml
不保留注释,也不保留flow style中的间距。如果您关心布局,以便您的 YAML 更易于人类阅读,那么您应该尽可能对叶节点使用流样式。这是使用时的默认转储样式YAML(typ='fast')
。
当您像输入一样嵌套流样式时,这些节点上的流样式将被保留,并完成标准格式设置(如果行变大,则换行除外,所有内容都在一行上)。
设置缩进级别仅影响块样式结构。
您应该将输入更改为仅叶节点流样式,以获得更好的可读性:
root:
children: {key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}
这将加载到与您的输入相同的数据结构。
有了它,您现在可以执行以下操作:
import sys
import ruamel.yaml
yml_file = 'input.yaml'
new_project_name = 'NPN'
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 4096
with open(yml_file, 'r') as file:
print("Modifying file: '%s'..." % str(file))
data = yaml.load(file)
npn_lower = new_project_name.lower()
data['root'][npn_lower] = m = ruamel.yaml.comments.CommentedMap([
('key', "%s" % npn_lower),
('test_version', "{{ %s_version | default(\'1.0.0-SNAPSHOT\') }}" % npn_lower)
])
m.fa.set_flow_style()
with open('output.yaml', 'w') as fp:
yaml.dump(data, fp)
打印:
Modifying file: '<_io.TextIOWrapper name='input.yaml' mode='r' encoding='UTF-8'>'...
并具有output.yaml
:
root:
children: {key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}
npn: {key: npn, test_version: "{{ npn_version | default('1.0.0-SNAPSHOT') }}"}
注意事项:
添加一个 CommentedMap,因为在普通 dict 上您不能单独设置流样式,并且您需要这样做,因为这不再是嵌套的流样式。元素作为元组列表添加,与旧版本的 Python 一样,键顺序不能保证与输入中的相同。您还可以创建一个空
CommentedMap()
并一次添加一个键/值对。在尝试过程中(以及此处提供的代码),更改输入文件始终是一个坏主意,因为对于每次测试运行,您的输入都必须还原。
推荐阅读
- javascript - 如何在排序的数字列表中合并连续的数字?
- python - 当参数恒定时,是否适合在 python 类中使用闭包?
- python - 在 Scala Spark 和 PySpark 之间传递多个 DataFrame
- javascript - 当应用程序在后台时,如何让服务人员处理推送?
- pyspark - 在 pyspark 数据框中查找连续数据
- reactjs - 在 Android 上强制退出并重新打开应用程序后,组件上的引用为空
- xml - 使用正确的 xpath 捕获值
- c - 为什么将 double 转换为 int 可能会产生不同的结果?
- javascript - 如果条件不满足,则数组中返回空值和逗号,JS映射箭头函数
- python-3.x - 如何针对 Anaconda Python 中的 R(相关强度)值应用阈值标签?