【问题标题】:make config yaml more readable for nested list使配置 yaml 对嵌套列表更具可读性
【发布时间】:2021-10-30 12:55:01
【问题描述】:

我有这个示例 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 中的嵌套列表?

【问题讨论】:

    标签: python-3.x dictionary yaml ruamel.yaml


    【解决方案1】:

    如果使用,只需设置一次yaml.default_flow_style。但在 往返模式这只影响新创建的dicts 和lists。所有加载的数据结构都有明确设置和保留的块/流样式,不受.default_flow_style 的影响。 将 YAML 文档以增量方式转储到文件中几乎总是一个坏主意,您可以通过这种方式轻松创建无效/可卸载的 YAML 文档。

    据记录,ruamel.yaml 明确尝试保留 block 样式, 相反(大部分)规范化流式。 一个很好的测试,看看你是否可以实现你想要的输出是通过往返预期的 YAML 格式 看看ruamel.yaml 是否可以重新生成您的格式(如果它确实检查节点 如果您想从头开始创建它们的特殊属性)。

    在您的情况下,您会注意到 ruamel.yaml 并没有专门处理这些嵌套的流式列表 并将它们标准化为不需要的样本格式。

    如果嵌套序列的元素之间存在 cmets,您会注意到 ruamel.yaml 目前无法妥善处理这些问题。他们不会迷路,但他们 插入到自己的行中,这很好地表明尝试插入空 外部序列元素之间的 cmets 也会产生额外的换行符。

    我的主要建议是不要嵌套流样式序列。

    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,但您需要在 IMO 如果人类处理引用的不一致(abc vs '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
    

    【讨论】:

      猜你喜欢
      • 2016-09-08
      • 2020-07-06
      • 2013-04-26
      • 1970-01-01
      • 2017-05-18
      • 2017-11-26
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      相关资源
      最近更新 更多