在 Python 中往返转储 YAML 时有没有办法保持顺序?
Is there a way to preserve order while round-trip dumping YAML in Python?
我正在尝试从 YAML 文件加载一些数据并将其放回:
services:
dc01:
sw-06-50001:
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003:
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
有了这个:
import ruamel.yaml as yaml
with open('filename.yml', 'r') as stream:
outdata = yaml.load(stream,Loader=yaml.Loader)
yaml.dump(outdata,'filename_out.yml')
我需要保留列表中的所有格式和数据顺序,但输出转储导致按 sw-xx.. 键的字母顺序排序:
services:
dc01:
sw-06-50001:
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-06-50003:
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
如何在转储时保持条目的原始顺序?
您正在进行往返,但您没有使用 ruamel.yaml 的往返功能。相反,你是
使用过时的 PyYAML 兼容性 load
和 dump
函数。
相反,您应该实例化一个 ruamel.yaml.YAML()
实例并使用该实例的 load
和 dump
方法,
它们默认为保留顺序(以及评论、标签名称等)的往返行程
import sys
import ruamel.yaml
yaml_str = """\
services:
dc01:
sw-06-50001: # first
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003: # third
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
"""
yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
给出:
services:
dc01:
sw-06-50001: # first
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003: # third
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
或者,如果您在文件中有 YAML:
from pathlib import Path
from ruamel.yaml import YAML
# the recommended extension for YAML files has been .yaml since 2006.
file_name = Path('filename.yaml')
file_out = Path('filename_out.yaml')
yaml = YAML()
outdata = yaml.load(file_name)
yaml.dump(outdata, file_out)
我正在尝试从 YAML 文件加载一些数据并将其放回:
services:
dc01:
sw-06-50001:
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003:
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
有了这个:
import ruamel.yaml as yaml
with open('filename.yml', 'r') as stream:
outdata = yaml.load(stream,Loader=yaml.Loader)
yaml.dump(outdata,'filename_out.yml')
我需要保留列表中的所有格式和数据顺序,但输出转储导致按 sw-xx.. 键的字母顺序排序:
services:
dc01:
sw-06-50001:
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-06-50003:
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
如何在转储时保持条目的原始顺序?
您正在进行往返,但您没有使用 ruamel.yaml 的往返功能。相反,你是
使用过时的 PyYAML 兼容性 load
和 dump
函数。
相反,您应该实例化一个 ruamel.yaml.YAML()
实例并使用该实例的 load
和 dump
方法,
它们默认为保留顺序(以及评论、标签名称等)的往返行程
import sys
import ruamel.yaml
yaml_str = """\
services:
dc01:
sw-06-50001: # first
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003: # third
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
"""
yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
给出:
services:
dc01:
sw-06-50001: # first
servers:
- {ip: 10.255.206.12, port: 50001, weight: 100}
- {ip: 10.255.206.13, port: 50001, weight: 90}
virtual: {ip: 192.168.1.4, port: 50001}
sw-09-50002:
servers:
- {ip: 10.255.206.18, port: 50002, weight: 100}
- {ip: 10.255.206.19, port: 50002, weight: 90}
virtual: {ip: 192.168.1.4, port: 50002}
sw-06-50003: # third
servers:
- {ip: 10.255.206.12, port: 50003, weight: 100}
- {ip: 10.255.206.13, port: 50003, weight: 90}
virtual: {ip: 192.168.1.4, port: 50003}
sw-09-50004:
servers:
- {ip: 10.255.206.18, port: 50004, weight: 100}
- {ip: 10.255.206.19, port: 50004, weight: 90}
virtual: {ip: 192.168.1.4, port: 50004}
或者,如果您在文件中有 YAML:
from pathlib import Path
from ruamel.yaml import YAML
# the recommended extension for YAML files has been .yaml since 2006.
file_name = Path('filename.yaml')
file_out = Path('filename_out.yaml')
yaml = YAML()
outdata = yaml.load(file_name)
yaml.dump(outdata, file_out)