使用 ruamel.yaml,如何使带有 NEWLINE 的变量成为不带引号的多行

Tob*_*son 5 python json ruamel.yaml

我正在生成用作协议的 YAML,其中包含一些生成的 JSON。

import json
from ruamel import yaml
jsonsample = { "id": "123", "type": "customer-account", "other": "..." }
myyamel = {}
myyamel['sample'] = {}
myyamel['sample']['description'] = "This example shows the structure of the message"
myyamel['sample']['content'] = json.dumps( jsonsample, indent=4, separators=(',', ': '))
print yaml.round_trip_dump(myyamel, default_style = None, default_flow_style=False, indent=2, block_seq_indent=2, line_break=0, explicit_start=True, version=(1,1))
Run Code Online (Sandbox Code Playgroud)

然后我得到这个输出

%YAML 1.1
---
sample:
  content: "{\n    \"other\": \"...\",\n    \"type\": \"customer-account\",\n    \"\
  id\": \"123\"\n}"
description: This example shows the structure of the message
Run Code Online (Sandbox Code Playgroud)

现在对我来说,如果我能够使多行行从管道开始格式化,看起来会好得多|

我想看到的输出是这样的

%YAML 1.1
---
sample:
  content: |
    {    
       "other": "...",
       "type": "customer-account",
       "id": "123"
    }
description: This example shows the structure of the message
Run Code Online (Sandbox Code Playgroud)

看看这读起来有多容易......

那么我该如何在 python 代码中解决这个问题呢?

Ant*_*hon 5

你可以做:

import sys
import json
import ruamel.yaml

yaml = ruamel.yaml.YAML()
yaml.version = (1, 1)

jsonsample = { "id": "123", "type": "customer-account", "other": "..." }
myyamel = {}
myyamel['sample'] = {}
myyamel['sample']['description'] = "This example shows the structure of the message"
myyamel['sample']['content'] = json.dumps( jsonsample, indent=4, separators=(',', ': '))

ruamel.yaml.scalarstring.walk_tree(myyamel)

yaml.dump(myyamel, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

这使:

%YAML 1.1
---
sample:
  description: This example shows the structure of the message
  content: |-
    {
        "id": "123",
        "type": "customer-account",
        "other": "..."
    }
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

  • 由于您使用的是普通字典,因此 YAML 的打印顺序取决于实现和密钥。如果您希望将顺序固定到您的作业,请使用:

      myyamel['sample'] = yaml.comments.CommentedMap()
    
    Run Code Online (Sandbox Code Playgroud)
  • print(yaml.round_trip_dump)如果打印返回值,指定要写入的流,则永远不应该使用,这样更有效。

  • walk_tree将所有包含换行符的字符串递归地转换为块样式模式。您还可以明确地执行以下操作:

      myyamel['sample']['content'] = yaml.scalarstring.PreservedScalarString(json.dumps( jsonsample, indent=4, separators=(',', ': ')))
    
    Run Code Online (Sandbox Code Playgroud)

在这种情况下你不需要打电话walk_tree()


即使您仍在使用 Python 2,您也应该开始习惯使用函数print而不是print语句。为此,请在每个 Python 文件的顶部添加:

from __future__ import print_function
Run Code Online (Sandbox Code Playgroud)