【问题标题】:Keeping offset indentation of YAML file using python ruamel-yaml使用 python ruamel-yaml 保持 YAML 文件的偏移缩进
【发布时间】:2020-05-23 09:26:19
【问题描述】:

我正在尝试使用 ruamel-yaml 来实现以下目标我有一个带有一组变量的 YAML 文件(请注意,所有键都以缩进 6 开头):

      app:
        version: 'latest'
        env: 'test'

      #auth
      auth_endpoint: 'http://localhost/login'
      auth_token: 23NSDQD94NFDFKF0SQS

我的想法是为用户提供一个 python 脚本,该脚本将生成配置文件但具有覆盖的值,所以基本上我将解析参数,加载 YAML 文件更改值并使用更新的值转储 YAML 文件和这个一切正常,除非文件被转储,缩进 6 丢失,除了 cmets,(见下面的代码)

app:
  version: 'latest'
  env: 'test'

      #auth
auth_endpoint: 'http://localhost/login'
auth_token: 23NSDQD94NFDFKF0SQS

现在这个缩进很重要,因为这个文件将被解析并合并到一个更大的 YAML 文件中

def update_yaml(file):
  yaml = ruamel.yaml.YAML()
  yaml.indent(mapping=6)
  config_yaml = yaml.load(file)
  # value changing code ommited for readability
  with open(os.path.join(sys.path[0], "config.yml"), 'w') as file:
    yaml.dump(config_yml, file)

我已经用缩进方法尝试了一些东西,但没有成功,知道如何保持这个原始缩进吗?

【问题讨论】:

    标签: python yaml ruamel.yaml


    【解决方案1】:

    首先,并非所有键的缩进都是 6,因为 键 versionenv,它们是映射的一部分,是 根级键app仅缩进两个位置

    ruamel.yaml 将强制您的输出在缩进方面保持一致。所有映射都将缩进相同,所有序列也将缩进(尽管映射和序列可能不同)。因为你想要的输出是 不一致,你需要做一些后期处理:

    import sys
    import ruamel.yaml
    
    yaml_str = """\
          app:
            version: 'latest'
            env: 'test'
    
          #auth
          auth_endpoint: 'http://localhost/login'
          auth_token: 23NSDQD94NFDFKF0SQS
    """
    
    class PushRootLeft:
        def __init__(self, positions=42):
            self.positions = positions
    
        def __call__(self, s):
            result = []
            for line in s.splitlines(True):
                sline = line.strip()
                if not sline or sline[0] == '#':
                    result.append(line)
                else:
                    result.append(' ' * self.positions + line)
            return ''.join(result)
    
    yaml = ruamel.yaml.YAML()
    yaml.indent(mapping=2) # not necessary, this is the default
    yaml.preserve_quotes = True
    
    data = yaml.load(yaml_str)
    print('123456780') # just to better see the alignment of the actual YAML output
    yaml.dump(data, sys.stdout, transform=PushRootLeft(6))
    

    给出:

    123456780
          app:
            version: 'latest'
            env: 'test'
    
          #auth
          auth_endpoint: 'http://localhost/login'
          auth_token: 23NSDQD94NFDFKF0SQS
    

    您应该将.preserve_quotes 设置为某些(损坏的)解析器不喜欢您的 URL 中的冒号未加引号, 将其解释为值指示符,即使它后面没有空格。

    您必须为 cmets 做一些特别的事情,因为在往返过程中它知道它最初出现在哪一列中,并会尝试在那里恢复(除非某些值更改推动它正确)。

    recommended extension for YAML files has been .yaml 自 2006 年 9 月以来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 2019-08-05
      • 2021-05-02
      • 2021-05-10
      • 2019-09-08
      • 2021-12-17
      • 1970-01-01
      相关资源
      最近更新 更多