当您以ruamel.yaml
的默认往返模式加载 YAML 文件时,会将一个序列加载到CommentedMap
(在 中定义
ruamel.yaml.comments.py
)中。那CommentedMap
是
OrderedDict
(或ruamel.ordereddict
在 Python2 上)的子类。
因此,您可以做的一件事是将您的转换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
与 a 相同的方式表示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)
结果与以前完全相同。