【问题标题】:Using ruamel.yaml to keep multiline strings with same indentation Python使用 ruamel.yaml 保持多行字符串具有相同的缩进 Python
【发布时间】:2018-06-29 14:00:25
【问题描述】:

我正在尝试制作一些 YAML 文件,但我正在努力获取正确格式的 YAML 文件。我试图让值的字符串都在同一个缩进上,但我似乎无法让它工作。

ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: The is the first line of the sentence and then we continue 
    on to the second line but this line should be indented to match the 
    first line of the string. 

这是我所拥有的,但我正在寻找:

ResourceIndicators:
  version: 1.0.0
  name: This is the name
  neType: Text
  category: Text
  description: The is the first line of the sentence and then we continue 
               on to the second line but this line should be indented to 
               match the first line of the string. 

【问题讨论】:

    标签: yaml ruamel.yaml


    【解决方案1】:

    ruamel.yaml(或 PyYAML)中没有选项或简单的方法可以得到你想要的。

    description 映射键的值是普通标量,您可能已将输出宽度设置为 70(或类似值)以获得该结果。该值是一个普通样式的标量,可以在由非空格字符包围的任何空格上断开。

    您可能考虑过使用块样式的文字标量,但尽管

      description: |-
                   The is the first line of the sentence and then we continue
                   on to the second line but this line should be indented to match the
                   first line of the string.
    

    几乎看起来相似,它实际上在该字符串中加载了两个额外的换行符。 即使您在转储之前预处理该标量并在加载后对其进行后处理以尝试使用显式块缩进指示器也不会给您超过 9 个位置(因为它被限制为单个数字)并且您拥有的不止这些。

    如果以下格式可以接受:

    ResourceIndicators:
      version: 1.0.0
      name: This is the name
      neType: Text
      category: Text
      description: |-
        The is the first line of the sentence and then we continue
        on to the second line but this line should be indented to
        match the first line of the string.
    

    你可以用一个小函数wrapped做到这一点:

    import sys
    import textwrap
    import ruamel.yaml
    from ruamel.yaml.scalarstring import PreservedScalarString
    
    yaml_str = """\
    ResourceIndicators:
      version: 1.0.0
      name: This is the name
      neType: Text
      category: Text
      description: The is the first line of the sentence and then we continue
        on to the second line but this line should be indented to match the
        first line of the string.
    """
    
    def wrapped(s, width=60):
        return PreservedScalarString('\n'.join(textwrap.wrap(s, width=width)))
    
    yaml = ruamel.yaml.YAML()
    yaml.preserve_quotes = True
    data = yaml.load(yaml_str)
    data['ResourceIndicators']['description'] = \
        wrapped(data['ResourceIndicators']['description'])
    yaml.dump(data, sys.stdout)
    

    但请注意,加载后您必须将值中的换行符替换为空格。

    如果这不是一个选项,您需要创建一个“IndentedPlainString”类,并使用一个特殊的表示器来执行额外的缩进。

    【讨论】:

      猜你喜欢
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 2020-04-14
      • 2016-02-05
      • 2019-06-23
      • 1970-01-01
      相关资源
      最近更新 更多