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

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

我有这样的代码:

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 Build configuration overview docs

如何获得?
当我尝试使用 [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"]不同。

最佳答案

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

但是,既然您设置了 .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,但其子类,保留有关其原始信息的信息 流/ block 风格。

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

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

关于python - 如何在保留引号的同时将字符串设置为 yaml 值列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60132660/

相关文章:

yaml - 获取 bash 命令的输出并将其放入 yaml 中的消息中以进行 GitHub 操作?

python - self.prepared_data 中存在多个索引字段

python - Pandas 在 Groupby 中重新索引日期

javascript - DriveApp.getStorageUsed() 与 DriveApp.getFiles() 返回的文件大小总和不匹配。

google-app-engine - 如何转让 Google Cloud 项目所有权?

json - YAML::Tiny 不支持 JSON::XS::Boolean

docker - 发布构建工件任务结果 'path does not exist'错误

python - 如何在一个文件的一行中输出 3 个项目?

python - 属性错误: 'MuParser' object has no attribute 'startRule'

kubernetes - GKE自定义内部服务域