问题
I am generating YAML which serves as a protocol, and it contains some generated JSON inside of it.
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))
Then I get this output
%YAML 1.1
---
sample:
content: "{\n \"other\": \"...\",\n \"type\": \"customer-account\",\n \"\
id\": \"123\"\n}"
description: This example shows the structure of the message
Now to me that could look much better
if I was able to make the multiline rows be formatted starting with a pipe |
The output that I want to see is this
%YAML 1.1
---
sample:
content: |
{
"other": "...",
"type": "customer-account",
"id": "123"
}
description: This example shows the structure of the message
See how much easier this is to read ...
So how do I solve this in python code ?
回答1:
You can do:
import sys
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=(',', ': '))
yaml.scalarstring.walk_tree(myyamel)
yaml.round_trip_dump(myyamel, sys.stdout, default_style = None, default_flow_style=False, indent=2, block_seq_indent=2, line_break=0, explicit_start=True, version=(1,1))
which gives:
%YAML 1.1
---
sample:
description: This example shows the structure of the message
content: |-
{
"id": "123",
"type": "customer-account",
"other": "..."
}
Some notes:
since you are using a normal dict the order in which your YAML is printed is implementation and key dependent. If you want the order to be fixed to your assignments use:
myyamel['sample'] = yaml.comments.CommentedMap()
- you should never use
print(yaml.round_trip_dump)
if you print the return value, specify the stream to write to, that is more efficient. walk_tree
converts all strings that have a newline in them to block style mode recursively. You can also explicitly do:myyamel['sample']['content'] = yaml.scalarstring.PreservedScalarString(json.dumps( jsonsample, indent=4, separators=(',', ': ')))
in which case you don't need to call
walk_tree()
Even though you are still working on Python 2, you should start getting used to using the print
function instead of the print
statement. For that include at the top of each of your Python files:
from __future__ import print_function
来源:https://stackoverflow.com/questions/44068782/using-ruamel-yaml-how-can-i-make-vars-with-newlines-be-multiline-without-quotes