如何在YAML文件中加载/导出十六进制值并保留注释?
解决方案:保留注释的同时处理YAML十六进制值
要实现加载时保留注释、输出时十六进制值仍以0x格式呈现,且保持原YAML结构,你可以用ruamel.yaml的RoundTripLoader(默认typ='rt')配合自定义构造器和表示器,无需切换到丢失注释的base模式。具体实现如下:
1. 自定义HexInt类型与构造器
编写构造器识别YAML中的十六进制整数字面量,将其加载为自定义HexInt类型(区别于普通int):
import ruamel.yaml class HexInt(int): pass def hex_int_constructor(loader, node): value = loader.construct_scalar(node) # 识别十六进制格式的数字字符串 if isinstance(value, str) and value.startswith(('0x', '0X')): return HexInt(value, 16) # 非十六进制整数按默认逻辑处理 return int(value) # 给RoundTripConstructor注册自定义整数构造器 ruamel.yaml.add_constructor( 'tag:yaml.org,2002:int', hex_int_constructor, Constructor=ruamel.yaml.RoundTripConstructor )
2. 注册十六进制表示器
用你之前的表示器逻辑,注册到RoundTripDumper上,确保输出时以0x格式呈现:
def hex_int_representer(dumper, data): return dumper.represent_scalar('tag:yaml.org,2002:int', hex(data)) ruamel.yaml.add_representer( HexInt, hex_int_representer, Dumper=ruamel.yaml.RoundTripDumper )
3. 加载与转储示例
使用round_trip_load/round_trip_dump方法,它们默认调用RoundTrip系列加载器/转储器,天然保留注释和原结构:
# 加载输入YAML文件 with open('input.yaml', 'r') as f: yaml_data = ruamel.yaml.round_trip_load(f) # (可选)修改十六进制值,比如将myvalue改为0xFF yaml_data['myvalue'] = HexInt(0xFF) # 转储到输出文件,保留所有注释和结构 with open('output.yaml', 'w') as f: ruamel.yaml.round_trip_dump(yaml_data, f, default_flow_style=False)
效果验证
输入YAML:
myvalue: 0x12 # This is my value othervalue: "foo" bar: value1: true # This value is true value2: 4627
输出YAML会完整保留注释、缩进和结构,myvalue会以0x12(或修改后的0xff)格式输出,而非十进制数值。
核心逻辑是利用RoundTrip系列工具保留原YAML格式,通过自定义类型标记十六进制值,再用表示器指定输出格式,完美平衡注释保留和十六进制需求。
内容的提问来源于stack exchange,提问作者Nosullya
相关产品推荐
相关产品推荐

