【问题标题】:How to set list with strings as a yaml value while preserving quotes?如何在保留引号的同时将带有字符串的列表设置为 yaml 值?
【发布时间】:2020-02-09 01:02:54
【问题描述】:

我有这样的代码:

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 Build configuration overview docs的 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"]不一样。

【问题讨论】:

  • args:- 是一个列表。为什么这对你不起作用?
  • 我只是从它开始,所以我想我不知道这两个是等价的 - 我的意思是 ["functions", "deploy", "publish_resized"]- 相同但相同。谢谢你的澄清:)
  • 不仅列表等价,双引号也是多余的,因为标量不能被标准 YAML 解析器解释为字符串。

标签: python google-cloud-platform yaml google-cloud-build ruamel.yaml


【解决方案1】:

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

但由于您设置了.default_flow_style,因此您期望 YAML 输出中的叶节点为流式是正确的,并且您可能遇到了 ruamel.yaml 的往返转储程序中的错误。

当 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"

这是因为映射和序列节点没有分别加载为dictlist,但其子类,保留有关其原始信息的信息 流/块样式。

您可以通过为您的列表构建该子类来模拟这一点:

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 添加后者 必要的。

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    相关资源
    最近更新 更多