python转换为yaml格式问题

时间:2016-05-18 16:23:12

标签: python yaml

我有以下简单的脚本

#!/usr/bin/env python

import yaml    

returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, '__id__': '/usr/bin/gen-motd.py'}}
returns = yaml.dump(returns, default_flow_style=False)
print returns

输出

file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed:
  __id__: /usr/bin/gen-motd.py
  __run_num__: 1
  changes:
    diff: "--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import\
      \ urllib2\n import socket\n import json\n import time\n"
  comment: File /usr/bin/gen-motd.py updated
  duration: 99.663
  name: /usr/bin/gen-motd.py
  pchanges:
    diff: "--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import\
      \ urllib2\n import socket\n import json\n import time\n"
  result: true
  start_time: '16:18:54.060168'

差异部分格式错误..我希望它返回类似

的内容
file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed: 
  __id__: /usr/bin/gen-motd.py
  __run_num__: 1
  changes: 
    diff: |
        --- 
        +++ 
        @@ -1,5 +1,7 @@
         #!/usr/bin/env python

        +import sys
        +import urllib2
         import socket
         import json
         import time
  comment: "File /usr/bin/gen-motd.py updated"
  duration: 99.663
  name: /usr/bin/gen-motd.py
  pchanges: 
    diff: |
        --- 
        +++ 
        @@ -1,5 +1,7 @@
         #!/usr/bin/env python

        +import sys
        +import urllib2
         import socket
         import json
         import time
  result: true
  start_time: "16:18:54.060168"

1 个答案:

答案 0 :(得分:2)

要实现这一目标,需要克服两个问题:

  • 你的行在换行符之前不能有空格,因为没有办法在文字样式标量中表示
  • 您需要提供一个例程,将带有换行符的字符串作为文字样式标量输出,或者使用支持该格式的YAML库,例如ruamel.yaml(免责声明:我是该程序包的作者)。

使用ruamel.yaml是更简单的方法,只需转换3级深度并包含换行符的字符串:

import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import LiteralScalarString

returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': '--- \n+++ \n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n \n+import sys\n+import urllib2\n import socket\n import json\n import time\n'}, '__id__': '/usr/bin/gen-motd.py'}}

for k in returns:
    for k1 in returns[k]:
        if not isinstance(returns[k][k1], dict):
            continue
        for k2 in returns[k][k1]:
            v = returns[k][k1][k2]
            try:
                if '\n' in v:
                    while ' \n' in v:
                        v = v.replace(' \n', '\n') # remove EOL spaces
                    returns[k][k1][k2] = LiteralScalarString(v)
            except TypeError:
                continue

yaml = ruamel.yaml.YAML()
yaml.dump(returns, sys.stdout)

您当然可以删除整个for构造并使用

returns = {'file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed': {'comment': 'File /usr/bin/gen-motd.py updated', 'pchanges': {'diff': PreservedScalarString('---\n+++\n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n\n+import sys\n+import urllib2\n import socket\n import json\n import time\n')}, 'name': '/usr/bin/gen-motd.py', 'start_time': '16:18:54.060168', 'result': True, 'duration': 99.663, '__run_num__': 1, 'changes': {'diff': PreservedScalarString('---\n+++\n@@ -1,5 +1,7 @@\n #!/usr/bin/env python\n\n+import sys\n+import urllib2\n import socket\n import json\n import time\n')}, '__id__': '/usr/bin/gen-motd.py'}}

无论哪种方式,这都会给你:

file_|-/usr/bin/gen-motd.py_|-/usr/bin/gen-motd.py_|-managed:
  start_time: '16:18:54.060168'
  comment: File /usr/bin/gen-motd.py updated
  duration: 99.663
  __id__: /usr/bin/gen-motd.py
  changes:
    diff: |
      ---
      +++
      @@ -1,5 +1,7 @@
       #!/usr/bin/env python

      +import sys
      +import urllib2
       import socket
       import json
       import time
  __run_num__: 1
  pchanges:
    diff: |
      ---
      +++
      @@ -1,5 +1,7 @@
       #!/usr/bin/env python

      +import sys
      +import urllib2
       import socket
       import json
       import time
  name: /usr/bin/gen-motd.py
  result: true

因为您使用的是dict,所以YAML文件中的键的顺序是不确定的。您可以直接使用returns实例(来自CommentedMap)和ruamel.yaml.comments构建PreservedScalarString,并控制YAML映射中的关键顺序。