在网上搜索自定义构造函数的用法时,我看到如下内容:
def some_constructor(loader, node):
    value = loader.construct_mapping(node, deep=True)
    return SomeClass(value)
其作用是什么deep=True?我在pyyaml 文档中没有看到它。
看来我需要它;我有一个由 pyyaml 表示器生成的 yaml 文件,它包括节点锚点和别名(如&id003和*id003);如果没有,deep=True我会得到包含锚点/别名的那些对象的浅地图。
您在文档中看不到的deep=True原因是您通常不需要将其用作 PyYAML 包的最终用户。
constructor.py如果您跟踪该用途中方法的使用,deep=您会发现construct_mapping()并construct_sequence()在类中BaseConstructor(),并且这两个方法都会调用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传入时才会执行。
粗略地说,如果数据来自生成器的构造函数,那么它会遍历该数据(在循环中for)直到生成器耗尽。通过这种机制,这些构造函数可以包含yield创建一个基础对象,其详细信息可以在yield. 因为它们只是yield此类构造函数中的一个,例如用于映射(构造为 Python dict):
def construct_yaml_map(self, node):
    data = {}
    yield data
    value = self.construct_mapping(node)
    data.update(value)
我将此称为两步过程(一步到yield方法结束的下一步。
在这样的两步构造函数中,data要生成的内容被构造为空,生成,然后填充。之所以如此,是因为您已经注意到了:递归。如果存在对data下面某处的 self 引用,data则在构造其所有子级之后无法构造它,因为它必须等待自身构造完成。
该deep参数间接控制是否递归地构建或附加到self.state_generators稍后要解析的列表中的潜在生成器的对象。
然后,构建 YAML 文档可以归结为构建顶级对象并循环遍历潜在的递归对象,直到self.state_generators没有生成器剩下(这一过程可能需要多次传递)。
| 归档时间: | 
 | 
| 查看次数: | 1711 次 | 
| 最近记录: |