python - 如何让 Python Yaml 库以人性化的方式保存?
问题描述
这是我得到的 Python 代码:
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)
我不断得到的:
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
我如何改变它来生产:
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
换句话说,我想:
避免在输出中使用引号和转义字符,以便非技术用户可以阅读和编辑这些配置文件。
理想情况下保留参数的顺序。
这是为了能够加载 YAML 文件,添加更多参数,并且仍然能够以人类友好的格式保存它。
解决方案
您的输出值中没有换行符 for Pagargaph
,因为您需要有一个块样式的文字标量(破折号修剪最后的换行符,加载这样的标量时通常会得到):
Pagargaph: |-
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
你应该使用ruamel.yaml
(免责声明:我是那个包的作者),它是专门为支持这种往返而开发的。得到你想做的事,例如:
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)
导致:
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
请注意:
- 该顺序保留在 ruamel.yaml 支持的任何 Python 版本(2.7、3.4+)
- 评论被保留
bbb
仅当您指定时,我添加的引号才会保留yaml.preserve_quotes = True
- 因为我们在位置 2 插入了两次,所以后者将前者撞到了位置 3。
您的用户必须有一定的纪律性,他们才能编辑 YAML 文件而不破坏它。他们还应该知道一些注意事项,例如普通(非引号)标量不能以某些特殊字符开头或包含特殊字符序列(:
后跟空格,#
前面是空格)
为了帮助防止您的用户犯编辑错误,您可以尝试在 YAML 文档的开头添加以下注释:
# please read the first few "rules" of How_to_edit at the bottom of this file
最后:
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.
如果包含上述内容,您可能不想在往返时保留引号。
推荐阅读
- ios - UITableView 应用程序在 cellForRow 委托方法调用时崩溃
- amazon-cloudformation - 路由未在预期时间内稳定以下资源未能创建 NATRoute。用户请求回滚
- python - 连接到 Jupyter Notebook 中的 sql DB 时出现错误
- swift - 可以实现 Void 和 Codable 的泛型
- python - python - 如何使用OpenCV处理的图像将小图像粘贴到python中心的另一个大图像上?
- sql-server - 创建动态表
- mongodb - 是否有在保存和更新时触发的前/后挂钩?
- jmeter - 我们可以在 Allure 报告中转换 Jmeter 报告吗?
- r - 对于 Dataframe 中的每个项目都想自动循环
- spring-boot - 404 用于春季启动时的静态图像