温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - How to set list with strings as a yaml value while preserving quotes?
google-cloud-build google-cloud-platform python ruamel.yaml yaml

python - 如何在保留引号的同时将字符串列表设置为Yaml值?

发布于 2020-04-26 10:31:06

我有这样的代码:

import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq    
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=2)
yaml.preserve_quotes = True
yaml.default_flow_style=None

CF2_cloudbuild = {
            'steps':[
            {'name': dq("gcr.io/cloud-builders/gcloud"),
            'args': ["functions", "deploy", "publish_resized"],
            'timeout': dq("1600s")}
            ]
            }

with open("file.yaml", 'w') as fp:
    yaml.dump(CF2_cloudbuild, fp)

这是以下内容file.yaml

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: [functions, deploy, publish_resized]
  timeout: "1600s"

我需要:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

为了使格式与有关构建配置文件的GCP文档兼容,请使用GCP构建配置概述文档

如何获得?
当我尝试使用[dq("functions"), dq("deploy"), dq("publish_resized")]功能时,我得到:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args:
  - "functions"
  - "deploy"
  - "publish_resized"
  timeout: "1600s"

我认为与["functions", "deploy", "publish_resized"]

查看更多

提问者
Wojtek
被浏览
11
Anthon 2020-02-09 15:46

正如@Stephen Rauch指出的那样,两个输出是等效的,您“需要”的一个输出具有流样式的序列,而您获得的一个是块样式的序列。任何YAML解析器都应该以相同的方式加载它。并且,如果您未明确添加双引号,ruamel.yaml则在需要时将其添加(例如,防止字符串true作为布尔值加载)。

但是,既然设置好了,.default_flow_style您就可以正确预期YAML输出中的叶子节点为流样式,并且您可能遇到了ruamel.yamlround-tripdumper中的错误

当ruamel.yaml加载您的预期输出时,它将保留

import sys
import ruamel.yaml

yaml_str = """
steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"
"""

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True

data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

这使:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

这是因为映射和序列节点未作为dictresp 加载list,但是其子类,用于保留有关其原始流/块样式的信息。

您可以通过为列表构造该子类来模拟此情况:

from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq
from ruamel.yaml.comments import CommentedSeq

def cs(*elements):
     res = CommentedSeq(*elements)
     res.fa.set_flow_style()
     return res


CF2_cloudbuild = {
            'steps':[
            {'name': dq("gcr.io/cloud-builders/gcloud"),
            'args': cs(dq(l) for l in ["functions", "deploy", "publish_resized"]),
            'timeout': dq("1600s")}
            ]
            }

yaml.dump(CF2_cloudbuild, sys.stdout)

这使:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

但是,同样,如果cloudbuilder软件使用的YAML解析器是一致的,则在您的示例中,流样式或任何双引号都不需要。如果需要,您可以依靠ruamel.yaml添加后者。