如何以人性化的方式保存Python Yaml库? [英] How to make Python Yaml library save in a human-friendly way?

查看:80
本文介绍了如何以人性化的方式保存Python Yaml库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我得到的Python代码:

  d = {'ToGoFirst':'aaa','Second ':'bbb','Pagargaph':
'''Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor inciiduntunt
ut labore et dolore magna aliqua 。''',
'整数':25}
以open('d.yaml','w')as f:
yaml.safe_dump(d,f,default_flow_style = False )

我不断得到的东西:

 整数:25 
Pagargaph: Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod\
\tempor inididunt \nut labore et dolore magna aliqua。
第二个:bbb
ToGoFirst:aaa

如何将其更改为生产:

  ToGoFirst:aaa 
Second:bbb
gargarph:
Lorem ipsum dolor坐在amet ,
consectetur adipiscing精英,
sed do eiusmod tempor indicidunt
ut Labore et dolore magna aliqua。
整数:25

换句话说,我想:


  1. 在输出中避免引号和转义字符,以便非技术用户可以读取和编辑这些配置文件。


  2. 理想地保留参数的顺序。


这是为了能够加载参数YAML文件,添加更多参数,并且仍然能够以人类友好的格式保存它。

解决方案

您的输出没有换行符 Pagargaph 的值中,为此,您需要具有块样式的文字标量(破折号修饰了最后的换行符,通常在加载这样的标量时会得到):

  Pagargaph:|-
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor inciiduntunt
ut labour et dolore magna aliqua 。

您应使用 ruamel.yaml (免责声明:我是该程序包的作者),该程序专门用于支持这种往返。要获得您想要的内容,例如:

  import sys 
import ruamel.yaml
从ruamel.yaml .scalarstring import PreservedScalarString as L

yaml_str = \
ToGoFirst:aaa
第二个:'bbb'#在此后面插入
整数:25


yaml = ruamel.yaml.YAML()
yaml.preserve_quotes =真
d = yaml.load(yaml_str)
#yaml。 indent(mapping = 4,sequence = 4,offset = 2)
尝试:
before_integer = [k in d中的k] .index('Integer')
,ValueError除外:
before_integer = len(d)
d.insert(before_integer,'Pagargaph',L('''Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labouret and dolore magna aliqua。'''))
d.insert(before_integer,'Something','extra',comment ='with comment')
yaml.dump(d ,sys.stdout)

导致:

  ToGoFirst:aaa 
Second:'bbb'#在此
S之后插入omething:额外的#带有注释的
Pagargaph:|-
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor indicidunt
ut labour et dolore玛格纳·阿里夸。
整数:25

请注意:




  • 该顺序将保留在ruamel.yaml(2.7,3.4+)支持的任何Python版本中

  • 保留注释

  • 仅在您指定 yaml.preserve_quotes = True bbb 周围添加的引号。 >

  • 由于我们在位置2插入了两次,后者将前者提高到位置3。



您的用户将必须受过一定的训练,以便他们能够编辑YAML文件而不破坏它。他们还应该知道一些警告,例如普通的(未加引号的)标量,不能以某些特殊字符开头或包含特殊字符序列(,后跟空格, 前加空格)



为帮助防止用户犯下编辑错误,您可以尝试添加以下内容在YAML文档开头的注释:

 #,请阅读此文件底部的How_to_edit的前几个规则 

,最后:

 操作方法:| 
编辑YAML文档很容易,但是有一些规则可以防止
意外调用其隐藏的功能。在下面的内容中,您至少需要阅读
并将其应用到将重要规则与次要
重要规则分开的分隔符。不太重要的部分很有趣,但是您可能
不需要了解它们。
1)此文件中的条目包括标量键(在':'之前)和标量
值(通常在':'之后,但请阅读规则3)。
2)标量不需要在其两边加上引号(单引号,或双引号),除非
开头
('%',' *','&','{','[','-')或标量的中间(':','#)
如果添加引号,请在和之前使用单引号在标量之后如果
是多余的,则程序可以将其删除。因此,如果有疑问,只需将
添加它们即可。
3)后面跟有:|的键引入了多行标量。指令
在多行标量中。这样的标量从':|'之后的下一行开始。
行需要缩进,直到标量和这些
缩进空间结束不是标量的一部分
多行sclar中的换行很难(即保留,而不是用空格替换的

如果看到`:| -`,则表示标量加载了结尾的换行符

4)空格后的所有内容如果在引号或多行字符串中没有
,则用井号(’#’)结婚。
---重要规则的结尾---
5)在单引号标量中,您可以通过将其加倍来获得单引号:
规则4:您可能永远不会需要那个
这被称为转义单引号。您可以使用双引号标量,但是
转义的规则要困难得多,因此请不要在家中尝试。
6)仅由 True和 False组成的标量(也包括全大写字母和
全部小写字母)在不加引号的情况下被加载为布尔值,在被引号
的情况下被加载为字符串。
7)仅由数字字符(0-9)组成的标量将作为数字加载。
如果有非数字,通常将它们作为字符串加载,但是标量
以'0x'和'0o'开头,而其余仅包含数字字符,
是特殊字符,需要用引号(如果不想用作(十六进制或八进制))
数字。

如果包含上述内容,则往返时可能不想保留报价。 / p>

Here is the Python code I've got:

d = {'ToGoFirst': 'aaa', 'Second': 'bbb', 'Pagargaph':
'''Lorem ipsum dolor sit amet, 
consectetur adipiscing elit, 
sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua.''',  
'Integer': 25}
with open('d.yaml', 'w') as f:
    yaml.safe_dump(d, f, default_flow_style=False)

What I keep getting:

Integer: 25
Pagargaph: "Lorem ipsum dolor sit amet, \nconsectetur adipiscing elit, \nsed do eiusmod\
  \ tempor incididunt \nut labore et dolore magna aliqua."
Second: bbb
ToGoFirst: aaa

How do I change it to produce:

ToGoFirst: aaa
Second: bbb
Pagargaph: 
  Lorem ipsum dolor sit amet, 
  consectetur adipiscing elit, 
  sed do eiusmod tempor incididunt 
  ut labore et dolore magna aliqua.
Integer: 25

In other words I want to:

  1. Avoid quotation marks and escape characters in the output so non-technical users can read and edit those config files.

  2. Ideally preserve the order of parameters.

This is to be able to load a YAML file, add more parameters and still be able to save it in a human-friendly format.

解决方案

Your output has no newlines in the value for Pagargaph, for that you would need to have a block-style literal scalar (the dash trims the final newline, you would normally get when loading such a scalar):

Pagargaph: |-
  Lorem ipsum dolor sit amet, 
  consectetur adipiscing elit, 
  sed do eiusmod tempor incididunt 
  ut labore et dolore magna aliqua.

You should use ruamel.yaml (disclaimer: I am the author of that package), which is specifically developed to support this kind of round-tripping. To get what you want do e.g.:

import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import PreservedScalarString as L

yaml_str = """\
ToGoFirst: aaa
Second: 'bbb'  # insert after this one
Integer: 25
"""

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
d = yaml.load(yaml_str)
# yaml.indent(mapping=4, sequence=4, offset=2)
try:
    before_integer = [k for k in d].index('Integer')
except ValueError:
    before_integer = len(d)
d.insert(before_integer, 'Pagargaph', L('''Lorem ipsum dolor sit amet, 
consectetur adipiscing elit, 
sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua.'''))  
d.insert(before_integer, 'Something', 'extra', comment='with a comment')
yaml.dump(d, sys.stdout)

resulting in:

ToGoFirst: aaa
Second: 'bbb'  # insert after this one
Something: extra # with a comment
Pagargaph: |-
  Lorem ipsum dolor sit amet, 
  consectetur adipiscing elit, 
  sed do eiusmod tempor incididunt 
  ut labore et dolore magna aliqua.
Integer: 25

Please note:

  • the order is preserved in any version of Python supported by ruamel.yaml (2.7, 3.4+)
  • the comment is preserved
  • the quotes that I added around bbb are preserved only if you specify yaml.preserve_quotes = True
  • since we insert twice at position 2, the latter bumps the former to position 3.

Your users will have to be a bit disciplined for them to be able to edit a YAML file and not break it. They should also know some of the caveats, such as that plain (non-quoted) scalars, cannot start with some special characters or contain special character sequences (: followed by space, # preceded by space)

To help prevent your users from making editing mistakes, you can try to add the following comment at the beginning of the YAML document:

# please read the first few "rules" of How_to_edit at the bottom of this file

and at the end:

How_to_edit: |
 Editing a YAML document is easy, but there are some rules to keep you from 
 accidently invoking its hidden powers. Of the following you need at least 
 read and apply the ones up to the divider separating the important from less 
 important rules. The less important ones are interesting, but you probably 
 won't need to know them.
 1) Entries in this file consist of a scalar key (before the ':') and a scalar 
    value (normally after the ':', but read rule 3). 
 2) Scalars do NOT need quotes (single: ', or double: ") around them, unless 
    you have a special character or characters combinations at the beginning 
    ('%', '*', '&', '{', '[', '- ') or in the middle  (': ', ' #) of the  scalar.
    If you add quotes use a single quote before and after the scalar . If 
    these are superfluous the program can remove them. So when in doubt just 
    add them.
 3) A key followed by ': |' introduces a multiline scalar. These instructions
    are in a multiline scalar. Such a scalar starts on the next line after ': |'.
    The lines need to be indented, until the end of the scalar and these 
    indentation spaces are not part of the scalar. 
    The newlines in a multiline sclar are hard (i.e. preserved, and not 
    substituted with spaces).
    If you see `: |-` that means the scalar is loaded with the trailing newline 
    stripped.
 4) Anything after a space followed by a hash (' #') is a comment, when not 
    within quotes or in a multiline string.
 --- end of the important rules ---
 5) Within single quoted scalars you can have a single quote by doubling it: 
       rule 4: 'you probably don''t ever need that'
    This is called escaping the single quote. You can double quote scalars, but 
    the rules for escaping are much more difficult, so don't try that at home.
 6) The scalars consisting solely of "True" and "False" (also all-caps and 
    all-lowercase) are loaded as booleans when unquoted, and as strings when 
    quoted. 
 7) Scalars consisting solely of number characters (0-9) are loaded as numbers.
    If there is a non-number they are usually loaded as strings, but scalars 
    starting with '0x' and '0o' and for the rest have only number characters,
    are special and need quotes if not intended as (hexadecimal resp. octal) 
    numbers.

If you include the above, you probably don't want to preserve quotes when round-tripping.

这篇关于如何以人性化的方式保存Python Yaml库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆