用多行字符串读写Yaml文件

用户名

我必须读取yaml文件,对其进行修改并使用pyYAML回写。一切正常,除非单引号中包含多行字符串值,例如,输入yaml文件看起来像

FOO:
  - Bar: '{"HELLO":
"WORLD"}'

然后将其读取data=yaml.load(open("foo.yaml"))并写入它会yaml.dump(data, fref, default_flow_style=False)生成类似

FOO:
- Bar: '{"HELLO": "WORLD"}'

即没有多余的Bar价值奇怪的是,如果输入文件具有类似

FOO:
- Bar: '{"HELLO":

    "WORLD"}'

即,一条额外的新行用于Bar价值,然后将其写回,将生成正确数量的新行。知道我在做什么错吗?

安通

您没有做错任何事情,但是您可能应该阅读YAML规范的更多内容。

根据PyYAML在单引号标量内实现的(过时的)1.1规范

在多行单引号标量中,换行符经受(流)行折叠,并且内容中排除任何尾随空白。

折行

行折叠允许将长行折断以提高可读性,同时保留单个长行的原始语义。折叠完成后,将保留以空行结尾的任何换行符。此外,即使结束非空行,也会保留任何特定的换行符。

这意味着您的前两个示例是相同的,因为读取换行符就好像有一个空格。

第三个示例有所不同,因为它实际上在装入之后包含换行符,因为“保留了以空行结尾的任何换行符”。为了理解为什么在加载时会回退,您必须知道PyYAML不会保留任何有关引用的信息(在第一个示例中也不包含单个换行符),它只是将标量加载到Python字符串中。在转储期间,PyYAML评估如何最好地编写该字符串以及它考虑的选项(除非您尝试使用的default_style参数强制执行操作dump()):纯样式,单引号样式,双引号样式。

PyYAML在可能的情况下将使用纯样式(不带引号),但是由于字符串以开头{,因此与该字符用作流样式映射的开始时会造成混淆(冲突)。因此报价是必要的。由于字符串中也有双引号,并且没有需要反斜杠转义PyYAML可以选择的“最干净”表示的字符是单引号样式,并且在这种样式中,它需要通过包含空行来表示换行与单引号标量一起使用。

我个人更喜欢使用块样式文字标量来表示您的最后一个示例:

FOO:
- Bar: |
  {"HELLO":
    "WORLD"}

但是如果您加载,然后使用PyYAML转储该文件,则其可读性将丢失。

尽管在YAML 1.2规范(将近10年前发布)中措辞有所不同,但行折叠的作用相同,因此,对于更新的YAML加载程序/转储程序,它可以以类似的方式“工作”。如果您preserve_quotes = TrueYAML()实例设置属性,则用于加载/转储YAML 1.2的我的包ruamel.yaml会正确维护块样式,但是在您的第一个示例中,它仍然摆脱了换行符。可以实现这一点(如ruamel.yaml所示,在折叠样式块标量中保留适当的换行符位置),但从未有人提出过这样的要求,这可能是因为人们是否希望对包装进行这种控制,所以他们首先使用块样式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章