本文介绍了pyyaml 的漂亮输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 python 项目,我想在其中使用 YAML (pyYaml 3.11),特别是因为它漂亮"并且用户在必要时可以在文本编辑器中进行编辑.但是,我的问题是,如果我将 YAML 带入 Python 应用程序(因为我需要)并编辑内容(因为我需要),那么编写新文档通常不像我开始时那么漂亮.

pyyaml 文档非常糟糕 - 甚至没有记录转储函数的参数.我发现 http://dpinte.wordpress.com/2008/10/31/pyaml-dump-option/.但是,我仍然缺少我需要的信息.(我开始看源码,但似乎不是最吸引人的.如果我在这里没有得到解决方案,那么这是我唯一的办法.)

我从一个看起来像这样的文档开始:

- 颜色绿色:输入:- 端口的东西:小部件提示:文件名widget-help : 选择文件名- 端口 target_path :小部件提示:路径价值:'东西'输出:- 端口值:小部件提示:字符串文字: |我迷路了,我找到了我饿得像狼一样.

加载到 python (yaml.safe_load( s )) 后,我尝试了几种方法将其转储出来:

>>> 打印 yaml.dump( d3, default_flow_style=False, default_style='' )- 颜色绿色:输入:- 端口的东西:小部件帮助:选择文件名小部件提示:文件名- 端口目标路径:价值:东西小部件提示:路径输出:- 端口值:小部件提示:字符串文字:'我迷路了,我找到了我饿得像狼一样.'

>>> 打印 yaml.dump( d3, default_flow_style=False, default_style='|' )- 颜色绿色":输入":- 端口的东西":小部件帮助":|-选择文件名小部件提示":|-文档名称- 端口目标路径":价值":|-事物小部件提示":|-小路输出":- 端口值":小部件提示":|-细绳文本":|我迷路了,我找到了我饿得像狼一样.

理想情况下,我希望短字符串"不使用引号,就像第一个结果一样.但是我希望将多行字符串写为块,就像第二个结果一样.我想从根本上说,我试图尽量减少文件中不必要的引号爆炸,我认为这会使在文本编辑器中编辑变得更加烦人.

有人有这方面的经验吗?

解决方案

如果你可以使用 ruamel.yaml(免责声明:我是这个增强版 PyYAML 的作者)你可以这样做:

import ruamel.yamlyaml_str = """\- 颜色绿色:输入:- 端口的东西:小部件提示:文件名widget-help : 选择文件名- 端口 target_path :小部件提示:路径价值:'东西'输出:- 端口值:小部件提示:字符串文字: |我迷路了,我找到了我饿得像狼一样."""数据 = ruamel.yaml.round_trip_load(yaml_str)资源="对于 ruamel.yaml.round_trip_dump(data, indent=5, block_seq_indent=3).splitlines(True) 中的行:res += 行 [3:]打印(资源)

你得到:

- 绿色:输入:- 端口的东西:小部件提示:文件名小部件帮助:选择文件名- 端口目标路径:小部件提示:路径价值:东西输出:- 端口值:小部件提示:字符串文字: |我迷路了,我找到了我饿得像狼一样.

不完全是你开始时所做的(但在这次往返之后它是稳定的).使用更新版本的 ruamel.yaml,您可以在该缩进中设置序列 - 的缩进和相对缩进.然而,后者也会影响您的顶级序列,从而影响后期处理.

重要的(对我来说)保留的东西:注释、锚点、映射合并和文字标量(使用 | 的多行)

I have a python project where I'd like to use YAML (pyYaml 3.11), particularly because it is "pretty" and easy for users to edit in a text editor if and when necessary. My problem, though, is if I bring the YAML into a python application (as I will need to) and edit the contents (as I will need to) then writing the new document is typically not quite as pretty as what I started with.

The pyyaml documentation is pretty poor - does not even document the parameters to the dump function. I found http://dpinte.wordpress.com/2008/10/31/pyaml-dump-option/. However, I'm still missing the information I need. (I started to look at the source, but it doesn't seem the most inviting. If I don't get the solution here, then that's my only recourse.)

I start with a document that looks like this:

- color green :
     inputs :
        - port thing :
            widget-hint : filename
            widget-help : Select a filename
        - port target_path : 
            widget-hint : path
            value : 'thing' 
     outputs:
        - port value:
             widget-hint : string
     text : |
            I'm lost and I'm found
            and I'm hungry like the wolf.

After loading into python (yaml.safe_load( s )), I try a couple ways of dumping it out:

>>> print yaml.dump( d3, default_flow_style=False, default_style='' )
- color green:
    inputs:
    - port thing:
        widget-help: Select a filename
        widget-hint: filename
    - port target_path:
        value: thing
        widget-hint: path
    outputs:
    - port value:
        widget-hint: string
    text: 'I''m lost and I''m found

      and I''m hungry like the wolf.

      '
>>> print yaml.dump( d3, default_flow_style=False, default_style='|' )
- "color green":
    "inputs":
    - "port thing":
        "widget-help": |-
          Select a filename
        "widget-hint": |-
          filename
    - "port target_path":
        "value": |-
          thing
        "widget-hint": |-
          path
    "outputs":
    - "port value":
        "widget-hint": |-
          string
    "text": |
      I'm lost and I'm found
      and I'm hungry like the wolf.

Ideally, I would like "short strings" to not use quotes, as in the first result. But I would like multi-line strings to be written as blocks, as with the second result. I guess fundamentally, I'm trying to minimize an explosion of unnecessary quotes in the file which I perceive would make it much more annoying to edit in a text editor.

Does anyone have any experience with this?

解决方案

If you can use ruamel.yaml (disclaimer: I am the author of this enhanced version of PyYAML) you can do:

import ruamel.yaml

yaml_str = """\
- color green :
     inputs :
        - port thing :
            widget-hint : filename
            widget-help : Select a filename
        - port target_path :
            widget-hint : path
            value : 'thing'
     outputs:
        - port value:
             widget-hint : string
     text : |
            I'm lost and I'm found
            and I'm hungry like the wolf.
"""

data = ruamel.yaml.round_trip_load(yaml_str)
res = ""
for line in ruamel.yaml.round_trip_dump(data, indent=5, block_seq_indent=3).splitlines(True):
    res += line[3:]
print(res)

you get:

- color green:
       inputs:
          - port thing:
                 widget-hint: filename
                 widget-help: Select a filename
          - port target_path:
                 widget-hint: path
                 value: thing
       outputs:
          - port value:
                 widget-hint: string
       text: |
            I'm lost and I'm found
            and I'm hungry like the wolf.

Not exactly what you did start out with (but after this round-trip it is stable). With more recent versions of ruamel.yaml you can set both the indent and the relative indent of a sequence - within that indent. The latter however also influences your top-level sequence, hence the post processing.

Important (to me) things that are preserved: comments, anchors, mapping merges, and literal scalars ( multi-line using |)

这篇关于pyyaml 的漂亮输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 22:48