pyyaml.Loader.construct_mapping 中的 deep=True 有什么作用?

What does deep=True do in pyyaml.Loader.construct_mapping?

在网上搜索自定义构造函数的用法时,我看到了这样的东西:

def some_constructor(loader, node):
    value = loader.construct_mapping(node, deep=True)
    return SomeClass(value)

deep=True 有什么作用?我在 pyyaml documentation.

中没有看到它

看来我需要它;我有一个由 py​​yaml 代表生成的 yaml 文件,它包含节点锚点和别名(如 &id003*id003);没有 deep=True 我会为那些包含 anchors/aliases.

的对象得到一个浅映射

您没有在文档中看到 deep=True 是因为您通常不需要将它用作 PyYAML 包的最终用户。

如果您跟踪 constructor.py 中使用 deep= 的方法的使用,您会在 class BaseConstructor() 中找到 construct_mapping()construct_sequence()并且这两个调用 BaseConstructor.construct_object()。 研究该方法中的相关代码为:

    if tag_suffix is None:
        data = constructor(self, node)
    else:
        data = constructor(self, tag_suffix, node)
    if isinstance(data, types.GeneratorType):
        generator = data
        data = next(generator)
        if self.deep_construct:
            for dummy in generator:
                pass
        else:
            self.state_generators.append(generator)

尤其是其中的 for 循环,只有在传入 deep=True 时才会执行。

Rougly 说如果数据来自构造函数是生成器,那么它将遍历该数据(在 for 循环中)直到生成器耗尽。通过这种机制,那些构造函数可以包含一个 yield 来创建一个基础对象,其详细信息可以在 yield 之后填写。因为它们在此类构造函数中只有一个 yield,例如对于映射(构造为 Python dicts):

def construct_yaml_map(self, node):
    data = {}
    yield data
    value = self.construct_mapping(node)
    data.update(value)

我将此称为两步过程(一步到方法末尾的 yield

在这样的两步构造函数中,要生成的 data 构造为空,生成,然后填充。由于您已经注意到:递归,所以必须如此。如果下面某处有对 data 的自引用,则 data 无法在其所有子项构造完成后构造,因为它必须等待自身构造完成。

deep 参数间接控制潜在生成器的对象是被递归构建还是附加到列表 self.state_generators 以供稍后解析。

构建 YAML 文档然后归结为构建顶级对象并循环遍历 self.state_generators 中的潜在递归对象,直到没有生成器留下(这个过程可能需要多次通过)。