使配置 yaml 对于嵌套列表更具可读性
make config yaml more readable for nested list
我有这个 YAML 示例:
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [['gender', 'male'], ['no_of_cars', 'three'],
['hair_color', 'black'], ['eye_color', 'brown']]
我想以输出 yaml 应该是这样的方式呈现它:
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [
['gender', 'male'],
['no_of_cars', 'three'],
['hair_color', 'black'],
['eye_color', 'brown']
]
我正在使用以下代码:
from ruamel.yaml import YAML as Ruamel
from pathlib import Path
yaml = Ruamel(typ='rt')
config_file = Path('/Users/test_config.yaml')
configs = yaml.load(config_file.read_text())
component_file="xyz.txt"
with open(component_file, 'w') as component:
for key, value in configs.items():
yaml.default_flow_style=None
yaml.dump({key: value}, component)
这里的想法是将现有的 YAML 文件转换为更易于阅读的格式。任何指示如何实现我正在寻找的格式 - 对于 YAML 中的嵌套列表?
如果使用,只需设置一次yaml.default_flow_style
。但在
往返模式只影响新创建的 dict
s 和 list
s。所有加载的数据结构都明确设置和保留了 block/flow 样式,并且不受 .default_flow_style
的影响。
以增量方式将 YAML 文档转储到文件几乎总是一个坏主意,您可以通过这种方式轻松创建 invalid/unloadable YAML 文档。
如文档所述,ruamel.yaml
明确尝试保留 block 样式,
相反(大部分)规范化流式。
一个很好的测试,看看你是否可以通过往返预期的 YAML 格式来实现你想要的输出
查看 ruamel.yaml
是否可以重新生成您的格式(以及它是否检查节点
如果您想从头开始创建它们,它们的特殊属性)。
在您的情况下,您会注意到 ruamel.yaml
没有专门处理这些嵌套的流式列表
并将它们标准化为不需要的样本格式。
如果嵌套序列的元素之间有注释,您会注意到
ruamel.yaml
目前无法正确处理这些。他们不会迷路,但他们
插入到他们自己的一行中,这很好地表明试图插入空行
外部序列元素之间的注释也会产生额外的换行符。
我的主要建议是不要嵌套流式序列。
import sys
import ruamel.yaml
yaml_str = """\
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [['gender', 'male'], ['no_of_cars', 'three'],
['hair_color', 'black'], ['eye_color', 'brown']]
"""
def no_nested_flow_style_seq(d):
done = False
if isinstance(d, dict):
for k, v in d.items():
no_nested_flow_style_seq(v) # you can have sequences as keys in YAML, but it is rare
elif isinstance(d, list):
for elem in d:
if not done and isinstance(elem, list):
done = True
d.fa.set_block_style()
no_nested_flow_style_seq(elem)
yaml = ruamel.yaml.YAML()
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
no_nested_flow_style_seq(data)
yaml.dump(data, sys.stdout)
给出:
people:
name: abc
address: 55 Oxford Street, San Jose 95134. CA
occupation: Travel Blogger
Hobby: Travelling
additional_interests: []
other_info:
- [gender, male]
- [no_of_cars, three]
- [hair_color, black]
- [eye_color, brown]
为(块式)映射获取 6 个空格的缩进大小
序列,就像在您的示例输出中一样,您可以
转储前设置 yaml.indent(mapping=6, sequence=6, offset=4)
。
然而,至于。人类的可读性,有一篇文章《程序缩进
和可理解性”(1983 年,Miara、Musselman、Navarro 和 Shneiderman
(后者因 Nassi-Shneiderman 图成名)
在 ACM 的通讯中),这表明编程语言的可理解性
对于 2-4 个空格的缩进是最佳的,并且对于更高的值减少。
我不知道对人类可读数据格式的具体研究,等等
事情高度依赖于你的习惯,因此很难
凭个人经验判断,但
我建议不要为 YAML 使用如此大的缩进。
以上加载到与您的两个 YAML 样本相同的数据结构(对于所有
正常处理,格式化信息当然存储在某处,但肯定
其他程序,在往返模式下不使用 ruamel.yaml 看不出有什么区别)。
您可以设置 yaml.preserve_quotes = True
,但在我看来您需要
如果人类处理引用的不一致(abc
vs 'Travelling'
)
是看这些文件。设置也加载相同的数据结构。
如果数据格式可以改变,你应该考虑改变值
other_info
到字典列表:
- gender: male
- no_of_cars: three
- hair_color: black
- eye_color: brown
或标记标量的列表,这将允许您将它们加载到它们的拟合 class 实例中
(例如检查允许的标量值):
- !Gender male
- !No_Of_Cars three
- !Hair_Color black
- !Eye_Color brown
我有这个 YAML 示例:
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [['gender', 'male'], ['no_of_cars', 'three'],
['hair_color', 'black'], ['eye_color', 'brown']]
我想以输出 yaml 应该是这样的方式呈现它:
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [
['gender', 'male'],
['no_of_cars', 'three'],
['hair_color', 'black'],
['eye_color', 'brown']
]
我正在使用以下代码:
from ruamel.yaml import YAML as Ruamel
from pathlib import Path
yaml = Ruamel(typ='rt')
config_file = Path('/Users/test_config.yaml')
configs = yaml.load(config_file.read_text())
component_file="xyz.txt"
with open(component_file, 'w') as component:
for key, value in configs.items():
yaml.default_flow_style=None
yaml.dump({key: value}, component)
这里的想法是将现有的 YAML 文件转换为更易于阅读的格式。任何指示如何实现我正在寻找的格式 - 对于 YAML 中的嵌套列表?
如果使用,只需设置一次yaml.default_flow_style
。但在
往返模式只影响新创建的 dict
s 和 list
s。所有加载的数据结构都明确设置和保留了 block/flow 样式,并且不受 .default_flow_style
的影响。
以增量方式将 YAML 文档转储到文件几乎总是一个坏主意,您可以通过这种方式轻松创建 invalid/unloadable YAML 文档。
如文档所述,ruamel.yaml
明确尝试保留 block 样式,
相反(大部分)规范化流式。
一个很好的测试,看看你是否可以通过往返预期的 YAML 格式来实现你想要的输出
查看 ruamel.yaml
是否可以重新生成您的格式(以及它是否检查节点
如果您想从头开始创建它们,它们的特殊属性)。
在您的情况下,您会注意到 ruamel.yaml
没有专门处理这些嵌套的流式列表
并将它们标准化为不需要的样本格式。
如果嵌套序列的元素之间有注释,您会注意到
ruamel.yaml
目前无法正确处理这些。他们不会迷路,但他们
插入到他们自己的一行中,这很好地表明试图插入空行
外部序列元素之间的注释也会产生额外的换行符。
我的主要建议是不要嵌套流式序列。
import sys
import ruamel.yaml
yaml_str = """\
people:
name: abc
address: '55 Oxford Street, San Jose 95134. CA'
occupation: 'Travel Blogger'
Hobby: 'Travelling'
additional_interests: []
other_info: [['gender', 'male'], ['no_of_cars', 'three'],
['hair_color', 'black'], ['eye_color', 'brown']]
"""
def no_nested_flow_style_seq(d):
done = False
if isinstance(d, dict):
for k, v in d.items():
no_nested_flow_style_seq(v) # you can have sequences as keys in YAML, but it is rare
elif isinstance(d, list):
for elem in d:
if not done and isinstance(elem, list):
done = True
d.fa.set_block_style()
no_nested_flow_style_seq(elem)
yaml = ruamel.yaml.YAML()
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
no_nested_flow_style_seq(data)
yaml.dump(data, sys.stdout)
给出:
people:
name: abc
address: 55 Oxford Street, San Jose 95134. CA
occupation: Travel Blogger
Hobby: Travelling
additional_interests: []
other_info:
- [gender, male]
- [no_of_cars, three]
- [hair_color, black]
- [eye_color, brown]
为(块式)映射获取 6 个空格的缩进大小
序列,就像在您的示例输出中一样,您可以
转储前设置 yaml.indent(mapping=6, sequence=6, offset=4)
。
然而,至于。人类的可读性,有一篇文章《程序缩进
和可理解性”(1983 年,Miara、Musselman、Navarro 和 Shneiderman
(后者因 Nassi-Shneiderman 图成名)
在 ACM 的通讯中),这表明编程语言的可理解性
对于 2-4 个空格的缩进是最佳的,并且对于更高的值减少。
我不知道对人类可读数据格式的具体研究,等等
事情高度依赖于你的习惯,因此很难
凭个人经验判断,但
我建议不要为 YAML 使用如此大的缩进。
以上加载到与您的两个 YAML 样本相同的数据结构(对于所有
正常处理,格式化信息当然存储在某处,但肯定
其他程序,在往返模式下不使用 ruamel.yaml 看不出有什么区别)。
您可以设置 yaml.preserve_quotes = True
,但在我看来您需要
如果人类处理引用的不一致(abc
vs 'Travelling'
)
是看这些文件。设置也加载相同的数据结构。
如果数据格式可以改变,你应该考虑改变值
other_info
到字典列表:
- gender: male
- no_of_cars: three
- hair_color: black
- eye_color: brown
或标记标量的列表,这将允许您将它们加载到它们的拟合 class 实例中 (例如检查允许的标量值):
- !Gender male
- !No_Of_Cars three
- !Hair_Color black
- !Eye_Color brown