我编写了一个简单的脚本,最后使用ruamel.yaml将其发布到YAML文件中(如下所示的示例)。我使用了collections.OrderedDict
,以便可以按字母顺序对键进行重新排序,但是即使使用json.load
/ json.dumps
将其重新排序并转换回字典后,我也无法将其打印出来。有序的时尚。
我了解YAML规范并不关心顺序,但是我个人希望YAML文件排序,使用ruamel.yaml
模块执行此操作的正确方法是什么?
logging.to_syslog: 'false'
statsbeat:
multicast_interface_name: 'p1p1'
primary_field_name: 'primary'
udp_address: '239.253.0.50:20016'
all_documents_index: 'statsall-${statsbeat.exchange_code}-${statsbeat.name}'
exchange_code: 'd'
primary_field_algorithm: 'range'
cloud_type: 'none'
primary_field_algorithm_range: '1-48'
name: 'otpr'
logging.files:
permissions: '0644'
rotateeverybytes: 52428800
keepfiles: 7
name: '${statsbeat.name}.log'
答案 0 :(得分:0)
以ruamel.yaml
的默认往返模式加载YAML文件时,
然后将序列加载到CommentedMap
(在
ruamel.yaml.comments.py
)。 CommentedMap
是的子类
OrderedDict
(或Python2上的ruamel.ordereddict
)。
因此,您可以做的一件事就是将OrderedDict
转换为CommentedMap
:
import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap
from collections import OrderedDict
data = OrderedDict([
('logging.to_syslog', 'false'),
('statsbeat', OrderedDict([
('multicast_interface_name', 'p1p1'),
('primary_field_name', 'primary'),
('udp_address', '239.253.0.50:20016'),
('all_documents_index', 'statsall-${statsbeat.exchange_code}-${statsbeat.name}'),
('exchange_code', 'd'),
('primary_field_algorithm', 'range'),
('cloud_type', 'none'),
('primary_field_algorithm_range', '1-48'),
('name', 'otpr'),
])),
('logging.files', OrderedDict([
('permissions', '0644'),
('rotateeverybytes', 52428800),
('keepfiles', 7),
('name', '${statsbeat.name}.log'),
])),
])
def comseq(d):
if isinstance(d, OrderedDict):
cs = CommentedMap()
for k, v in d.items():
cs[k] = comseq(v)
return cs
return d
data = comseq(data)
yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)
给出:
logging.to_syslog: 'false'
statsbeat:
multicast_interface_name: p1p1
primary_field_name: primary
udp_address: 239.253.0.50:20016
all_documents_index: statsall-${statsbeat.exchange_code}-${statsbeat.name}
exchange_code: d
primary_field_algorithm: range
cloud_type: none
primary_field_algorithm_range: 1-48
name: otpr
logging.files:
permissions: '0644'
rotateeverybytes: 52428800
keepfiles: 7
name: ${statsbeat.name}.log
(如果您希望像示例中那样使用多余的单引号,则可以强制转换字符串
从SingleQuotedScalarString
导入到ruamel.yaml.scalarstring
。
但是可能更容易的是指示代表
代表OrderedDict
的方式与CommentedMap
相同。假设
与data
相同的导入和定义,您可以这样做:
from ruamel.yaml.representer import RoundTripRepresenter
class MyRepresenter(RoundTripRepresenter):
pass
ruamel.yaml.add_representer(OrderedDict, MyRepresenter.represent_dict,
representer=MyRepresenter)
yaml = ruamel.yaml.YAML()
yaml.Representer = MyRepresenter
yaml.dump(data, sys.stdout)
结果与以前完全相同。