...

Pyyaml自定义构造器实现列表拼接

YAML中支持定义锚点和引用或者插入锚点。但是插入锚点只支持拼装字典类型。不支持拼接列表类型。
Pyyaml中可以通过自定义Constructor来实现。

如以下数据,我们这里定义一个!concat标记,表示拼接后面的锚点数据。

list1: &list1 [1, 2, 3]
list2: &list2 [4, 5]
foo: !concat [*list1, *list2]

实现代码如下:

def concat_constructor(loader: yaml.SafeLoader, node: yaml.SequenceNode):
    """
    把 YAML 中 !concat [A, B] 的 A、B 先解析出来然后合并成一个 list
    """
    # 1. 先解析子节点(支持锚点引用 *list1、*list2 等)
    lists = loader.construct_sequence(node, deep=True)
    # 2. 结果必须是 list 才能拼接
    if not all(isinstance(lst, list) for lst in lists):
        raise yaml.YAMLError("!concat 的参数必须全部是列表")
    # 3. 拼接并返回
    return sum(lists, [])

# 注册到 SafeLoader
yaml.SafeLoader.add_constructor("!concat", concat_constructor)

# -----------------------------
# 使用示例
yaml_text = """
list1: &list1 [1, 2, 3]
list2: &list2 [4, 5]
foo: !concat [*list1, *list2]
"""

data = yaml.safe_load(yaml_text)
print(data["foo"])   # [1, 2, 3, 4, 5]
posted @ 2025-07-22 18:42  韩志超  阅读(18)  评论(0)    收藏  举报