如何用ruamel.yaml区分YAML锚点定义与锚点引用?
区分ruamel.yaml中的锚点定义与引用
在ruamel.yaml默认加载逻辑中,锚点引用会被直接解析为原始节点的引用,导致无法通过节点的yaml_anchor()方法区分哪个键对应锚点定义、哪个对应引用。可以根据需求选择以下两种解决方案:
场景1:保留原始结构,不解析引用
如果不需要让引用指向原始节点,仅需区分定义和引用,加载时设置resolve=False,此时引用会以AnchorReference对象形式保留,直接判断类型即可:
import ruamel.yaml from ruamel.yaml.comments import AnchorReference yaml_str = """ foo: &some_anchor bar: 1 baz: *some_anchor """ yaml = ruamel.yaml.YAML() yaml.resolve = False # 关键:禁用引用解析,保留原始标记 data = yaml.load(yaml_str) for key, val in data.items(): if isinstance(val, AnchorReference): print(f"键 {key} 是锚点引用,引用锚点: {val.anchor}") else: anchor_obj = val.yaml_anchor() if anchor_obj and anchor_obj.anchor: print(f"键 {key} 是锚点定义,锚点名称: {anchor_obj.anchor}")
运行输出:
键 foo 是锚点定义,锚点名称: some_anchor 键 baz 是锚点引用,引用锚点: some_anchor
场景2:解析引用的同时区分定义与引用
如果需要让引用指向原始节点(即baz的值与foo的值为同一个对象),可以通过遍历YAML事件流,提前记录锚点的定义和引用对应的键:
import ruamel.yaml from ruamel.yaml.parser import Parser from ruamel.yaml.scanner import Scanner yaml_str = """ foo: &some_anchor bar: 1 baz: *some_anchor """ # 第一步:遍历事件流,记录锚点信息 anchor_def_map = {} # 锚点名称 -> 对应的定义键 anchor_ref_list = [] # 存储(引用键, 锚点名称) current_key = None scanner = Scanner(yaml_str) parser = Parser(scanner) for event in parser: # 处理带锚点的事件 if hasattr(event, 'anchor') and event.anchor: # 锚点定义事件(对应值为字典的情况) if isinstance(event, ruamel.yaml.events.MappingStartEvent): anchor_def_map[event.anchor] = current_key # 锚点引用事件 elif isinstance(event, ruamel.yaml.events.ScalarEvent) and event.anchor.startswith('*'): anchor_ref_list.append((current_key, event.anchor.lstrip('*'))) # 记录当前遍历到的键 elif isinstance(event, ruamel.yaml.events.ScalarEvent) and not event.anchor: current_key = event.value # 第二步:正常加载YAML数据(引用已解析为原始节点) yaml = ruamel.yaml.YAML() data = yaml.load(yaml_str) # 输出区分结果 print("锚点定义对应键:") for anchor, key in anchor_def_map.items(): print(f" 锚点 {anchor} → 键 {key}") print("\n锚点引用对应键:") for key, anchor in anchor_ref_list: print(f" 键 {key} → 引用锚点 {anchor}")
运行输出:
锚点定义对应键: 锚点 some_anchor → 键 foo 锚点引用对应键: 键 baz → 引用锚点 some_anchor
内容的提问来源于stack exchange,提问作者Avl8
相关产品推荐
相关产品推荐

