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.
中没有看到它
看来我需要它;我有一个由 pyyaml 代表生成的 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 dict
s):
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
中的潜在递归对象,直到没有生成器留下(这个过程可能需要多次通过)。
在网上搜索自定义构造函数的用法时,我看到了这样的东西:
def some_constructor(loader, node):
value = loader.construct_mapping(node, deep=True)
return SomeClass(value)
deep=True
有什么作用?我在 pyyaml documentation.
看来我需要它;我有一个由 pyyaml 代表生成的 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 dict
s):
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
中的潜在递归对象,直到没有生成器留下(这个过程可能需要多次通过)。