转储已解析的文档时是否可以保留YAML块结构?

Chr*_*tti 6 python yaml pyyaml python-3.x

我们使用PyYAML为不同的环境准备配置文件.但是我们的YAML阻止了完整性.

input.yml......

pubkey: |
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK
    EsUgJHXcpw7OPxRrCQIDAQAB
    -----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)

...使用python3执行此程序...

import yaml

with open('input.yml', mode='r') as f:
    parsed = yaml.safe_load(f)

with open('output.yml', mode='w') as f:
    yaml.dump(parsed, f)
Run Code Online (Sandbox Code Playgroud)

......产生这个output.yml......

pubkey: '-----BEGIN PUBLIC KEY-----

    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq

    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2

    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK

    EsUgJHXcpw7OPxRrCQIDAQAB

    -----END PUBLIC KEY-----

    '
Run Code Online (Sandbox Code Playgroud)

是否可以使用PyYAML保留块的结构?

Ant*_*hon 8

是的pyyaml,但是你必须提供自己的增强版本,至少包括safe_load使用的Scanner,Parser和Constructor,dump使用的Emitter,Serializer和Representer,以及提供类似字符串的专用类保持有关它的原始格式的信息.

这是添加到ruamel.yaml(免责声明:我是该软件包的作者)的一部分,因为它是从PyYAML派生的,并且仍然保持类似的设置.使用ruamel.yaml:

import sys
import ruamel.yaml

yaml_str = """\
pubkey: |
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK
    EsUgJHXcpw7OPxRrCQIDAQAB
    -----END PUBLIC KEY-----
"""
yaml = ruamel.yaml.YAML()  # defaults to round-trip
yaml.indent(mapping=4)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

给你:

import sys
import ruamel.yaml as yaml

yaml_str = """\
pubkey: |
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK
    EsUgJHXcpw7OPxRrCQIDAQAB
    -----END PUBLIC KEY-----
"""

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
yaml.dump(data, sys.stdout, Dumper=yaml.RoundTripDumper, indent=4)
Run Code Online (Sandbox Code Playgroud)

至少使用Python 2.7和3.5.

indent=4RoundTripDumper默认为两个空格缩进的必要条件,并且不保留文件的原始缩进(不这样做可以简化重新缩进YAML文件).

如果你不能切换到ruamel.yaml你应该能够使用它的源提取所需的所有更改,但如果你可以,你也可以使用其他功能,如注释和合并键名保存.

  • @MattDMo 是的,我有朝这个方向发展的计划。我在 [so] 上的几个答案已经处理了部分实现,但我想让 1.1/1.2 差异运行时可选(用于加载和转储)并且还重构代码。我将不得不详细阅读文档以及重构。1.2 的变化首先是使 YAML 成为 JSON 的超集(例如,1.1 不是浮点表示)。这是一个小版本,所以没有大的变化。Ruamel 是我的公司名称,这些字符是我孩子的(交织)首字母缩写。 (2认同)