如何阻止ruamel.yaml自动转换负浮点数的输出格式?
阻止ruamel.yaml修改负浮点数格式的方案
问题描述
读取如下YAML文件:
neg_number: -2.32870E+00 pos_number: 0.14618E+01
使用ruamel.yaml 0.18.6 dump后,负数格式被自动修改,正数格式保留:
neg_number: -0.23287E+01 pos_number: 0.14618E+01
使用的代码如下:
from ruamel import yaml yaml2 = yaml.YAML() yaml2.width = 9999 yaml2.preserve_quotes = True yaml2.indent(offset=4, sequence=4, mapping=4) with open('test3.yaml', 'r', encoding='utf-8') as f: pa = yaml2.load(f) with open('datadump.yaml', 'w') as file: yaml2.dump(pa, file)
解决方案
方法一:保留原始字符串格式(推荐)
让ruamel.yaml加载时直接保留浮点数的原始字符串,避免转换为float类型后被自动格式化:
from ruamel import yaml def float_constructor(loader, node): # 直接返回节点的原始字符串,不做数值转换 return node.value yaml2 = yaml.YAML() yaml2.width = 9999 yaml2.preserve_quotes = True yaml2.indent(offset=4, sequence=4, mapping=4) # 注册自定义构造器,覆盖默认的浮点数解析逻辑 yaml2.constructor.add_constructor('tag:yaml.org,2002:float', float_constructor) with open('test3.yaml', 'r', encoding='utf-8') as f: pa = yaml2.load(f) with open('datadump.yaml', 'w') as file: yaml2.dump(pa, file)
注意:此方法下数值以字符串形式存储,若后续需要进行计算,需手动转换为float类型。
方法二:自定义浮点数序列化格式
如果需要保留数值类型,同时控制输出格式,可以自定义表示器,强制按照原始格式输出:
from ruamel import yaml def float_representer(dumper, data): # 针对负数和正数分别指定格式 if data < 0: # 格式化保留5位小数,采用-2.32870E+00的形式 abs_val = abs(data) output_str = f"-{int(abs_val*100000)}.0E+00" else: # 正数保持原格式 output_str = f"{data:.5f}E+01" return dumper.represent_scalar('tag:yaml.org,2002:float', output_str) yaml2 = yaml.YAML() yaml2.width = 9999 yaml2.preserve_quotes = True yaml2.indent(offset=4, sequence=4, mapping=4) # 注册自定义表示器,覆盖默认的浮点数序列化逻辑 yaml2.representer.add_representer(float, float_representer) with open('test3.yaml', 'r', encoding='utf-8') as f: pa = yaml2.load(f) with open('datadump.yaml', 'w') as file: yaml2.dump(pa, file)
此方法适合需要保留数值类型的场景,可根据实际格式需求调整格式化字符串。
内容的提问来源于stack exchange,提问作者bk_ing
相关产品推荐
相关产品推荐

