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]