我一直在阅读 PyYAML 源代码,试图了解如何定义一个可以添加的正确构造函数add_constructor
。我现在对该代码的工作原理有了很好的理解,但我仍然不明白为什么其中的默认 YAML 构造函数SafeConstructor
是生成器。例如,方法construct_yaml_map
:SafeConstructor
def construct_yaml_map(self, node):
data = {}
yield data
value = self.construct_mapping(node)
data.update(value)
我了解生成器如何用于以下方式来存根一个对象,并且如果传递给BaseConstructor.construct_object
它,则仅使用来自节点的数据填充它:deep=False
construct_mapping
if isinstance(data, types.GeneratorType):
generator = data
data = generator.next()
if self.deep_construct:
for dummy in generator:
pass
else:
self.state_generators.append(generator)
而且我了解在forBaseConstructor.construct_document
的情况下如何生成数据。deep=False
construct_mapping
def construct_document(self, node):
data = self.construct_object(node)
while self.state_generators:
state_generators = self.state_generators
self.state_generators = []
for generator in state_generators:
for dummy in generator:
pass
我不明白的是存根数据对象并通过在construct_document
. 是否必须这样做以支持 YAML 规范中的某些内容,或者它是否提供了性能优势?
This answer on another question有点帮助,但我不明白为什么这个答案会这样:
def foo_constructor(loader, node):
instance = Foo.__new__(Foo)
yield instance
state = loader.construct_mapping(node, deep=True)
instance.__init__(**state)
而不是这个:
def foo_constructor(loader, node):
state = loader.construct_mapping(node, deep=True)
return Foo(**state)
我已经测试过后一种形式适用于其他答案上发布的示例,但也许我错过了一些极端情况。
我正在使用 3.10 版的 PyYAML,但看起来有问题的代码在 PyYAML 的最新版本(3.12)中是相同的。