使config yaml对嵌套列表更具可读性



我有这个示例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。但在此模式仅影响新创建的dictlist。所有加载的数据结构都明确设置和保留了它们的块/流样式,并且不受.default_flow_style的影响。将YAML文档增量转储到文件中几乎总是一个坏主意,这样很容易创建无效/不可加载的YAML文档。

如文档所述,ruamel.yaml显式地尝试保留风格,相反地(大多数情况下)规范化了心流风格。一个很好的测试是通过往返预期的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)。然而,关于。人的可读性,有文章的"程序缩进"和comprehensibility"(1983年,作者:Miara, Musselman, Navarro和schneiderman)(后者因纳西-施耐德曼图而出名)(ACM通讯),这表明了编程语言的可理解性对于2-4个空格的缩进是最优的,对于较大的值则减小。我不知道关于人类可读数据格式的具体研究,诸如此类事情高度依赖于你习惯了什么,因此很难做到根据个人经验判断,但是我建议不要在YAML中使用这么大的缩进。

上面的内容加载到与您的两个YAML示例相同的数据结构中正常的处理,格式化信息当然存储在某个地方,但肯定其他程序,不使用ruamel。Yaml在往返模式下没有区别)..你可以设置yaml.preserve_quotes = True,但在我看来你需要这样做处理引用的不一致性(abc'Travelling')如果人类看看这些文件。

如果数据格式可以更改,则应考虑更改的值other_info到字典列表:

- gender: male
- no_of_cars: three
- hair_color: black
- eye_color: brown

或标记标量的列表,这将允许您将它们加载到与其匹配的类实例中(例如,检查允许的标量值):

- !Gender male
- !No_Of_Cars three
- !Hair_Color black
- !Eye_Color brown

最新更新