如何强制ruamel.yaml新API输出块样式而非流样式?
解决ruamel.yaml新API强制字典块样式输出的问题
问题分析
你遇到的核心问题是混用了RoundTripRepresenter与typ="safe",且新API的样式配置逻辑和旧API存在差异:
RoundTripRepresenter是为往返序列化设计的,默认会保留原有数据的格式(包括流样式),会直接覆盖你设置的default_flow_style参数。- 新API(
YAML类)中,default_flow_style需要直接设置在实例上,无法通过dump()方法传参(这是旧API的用法)。
解决方案
方案1:移除RoundTripRepresenter(推荐,匹配你的需求)
既然你不关心往返序列化、不需要保留输入格式,直接使用默认YAML实例配置即可:
from ruamel.yaml import YAML from datetime import datetime # 创建YAML实例,无需指定typ="safe"(若需安全加载可保留,但需额外配置) yaml = YAML() # 强制所有字典使用块样式输出 yaml.default_flow_style = False # 可选:调整缩进格式,优化输出美观度 yaml.indent(mapping=2, sequence=4, offset=2) perfdata: dict[datetime, dict[int, float]] = {} performance_file = opts.mapdir / "performance.yaml" if performance_file.exists(): make_backup(performance_file) with performance_file.open("rt") as fin: perfdata = yaml.load(fin) perfdata[datetime.now().astimezone()] = normalized_time_per_row with performance_file.open("wt") as fout: yaml.dump(perfdata, fout)
方案2:使用Safe类型并自定义Representer(若必须保留安全加载特性)
如果需要保留typ="safe"的安全加载能力,需为SafeRepresenter添加自定义的字典表示逻辑,强制块样式:
from ruamel.yaml import YAML, SafeRepresenter from datetime import datetime # 自定义字典的块样式表示器 def dict_block_representer(dumper, data): return dumper.represent_mapping('tag:yaml.org,2002:map', data.items(), flow_style=False) # 自定义datetime的序列化格式(避免默认格式兼容问题) def datetime_representer(dumper, data): return dumper.represent_scalar('tag:yaml.org,2002:timestamp', data.isoformat()) yaml = YAML(typ="safe") yaml.Representer.add_representer(dict, dict_block_representer) yaml.Representer.add_representer(datetime, datetime_representer) # 确保全局块样式设置生效 yaml.default_flow_style = False # 后续加载、dump逻辑同方案1 perfdata: dict[datetime, dict[int, float]] = {} performance_file = opts.mapdir / "performance.yaml" if performance_file.exists(): make_backup(performance_file) with performance_file.open("rt") as fin: perfdata = yaml.load(fin) perfdata[datetime.now().astimezone()] = normalized_time_per_row with performance_file.open("wt") as fout: yaml.dump(perfdata, fout)
关键说明
- 移除
yaml.Representer = RoundTripRepresenter是解决问题的核心:它的样式保留逻辑会干扰全局样式设置,导致你的default_flow_style配置不生效。 - 新API中
default_flow_style=False会强制所有映射(字典)使用块样式;而设置为None时,程序会根据内容自动选择样式,这就是你设置None仍输出流样式的原因。
内容的提问来源于stack exchange,提问作者ClaireM
相关产品推荐
相关产品推荐

