在没有循环的方法中产生
yield in method without loop
我正在研究 ruamel.yaml API 使用源代码并找到 this strange pattern in code:
def construct_yaml_map(self, node):
# type: (Any) -> Any
data = CommentedMap()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
yield data
self.construct_mapping(node, data, deep=True)
self.set_collection_style(data, node)
这就使得有必要编写这样的代码 (inspired by the code in another place)
generator = yaml.constructor.construct_yaml_map(mapping_node)
# method does not run, only returns generator
data = next(generator)
# method executes until yield data (empty CommentedMap)
for _dummy in generator:
# on first iteration method continues until end
# no second iteration
pass
# or alternative expression
#try:
# next(generator)
#except StopIteration:
# pass
# now data is filled
在没有任何循环的方法中间使用这个 yield
有什么用?
Python 允许您创建递归数据结构,与
许多其他流媒体格式,YAML 允许您转储这些
import sys
import ruamel.yaml
data = dict(a=1)
data['b'] = data
yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)
给出:
&id001
a: 1
b: *id001
其中&id001
是YAML语言中的一个锚点,被*id001
引用,称为别名。
我不知道有什么方法可以在不使用多个语句的情况下在 Python 中创建 data
。你需要
对象(或其 id
)能够将其添加到自身。 YAML 加载器有类似的问题:
当它解析和构造一个组合(映射或序列)时,它会收集所有
children (key/value pairs resp. elements) 然后构造复合体。所以当复合
在 YAML 中(通过别名)引用自身,锚点的查找需要提供一个真实的,尽管
不完整、构造的 Python 对象(字典、列表,如果是标记对象,则可能是实例
一些 class).
这就是使用创建复合材料的两步过程的原因:您创建一个空对象,它
你交回去,所以如果有必要,可以在 anchor/alias table 中进行参考,
然后在代码的 post yield
部分填写它。
复合材料本身不需要在其中一个中有别名
他们的价值观或元素,但如果他们没有锚,他们可以
在一步过程中构建。但这会导致
不同的构造函数和调用 construct_yaml_map()
的代码
了解这些不同构造的对象。问题
转移,但不会消失,就像你可以创建递归
Python 不同,但仍然需要多个语句。
顺便说一句,这不是 ruamel.yaml
具体的。这段代码在 PyYAML 代码中,而且 AFAIK 仍然如此
ruamel.yaml
的来源。
我正在研究 ruamel.yaml API 使用源代码并找到 this strange pattern in code:
def construct_yaml_map(self, node):
# type: (Any) -> Any
data = CommentedMap()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
yield data
self.construct_mapping(node, data, deep=True)
self.set_collection_style(data, node)
这就使得有必要编写这样的代码 (inspired by the code in another place)
generator = yaml.constructor.construct_yaml_map(mapping_node)
# method does not run, only returns generator
data = next(generator)
# method executes until yield data (empty CommentedMap)
for _dummy in generator:
# on first iteration method continues until end
# no second iteration
pass
# or alternative expression
#try:
# next(generator)
#except StopIteration:
# pass
# now data is filled
在没有任何循环的方法中间使用这个 yield
有什么用?
Python 允许您创建递归数据结构,与 许多其他流媒体格式,YAML 允许您转储这些
import sys
import ruamel.yaml
data = dict(a=1)
data['b'] = data
yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)
给出:
&id001
a: 1
b: *id001
其中&id001
是YAML语言中的一个锚点,被*id001
引用,称为别名。
我不知道有什么方法可以在不使用多个语句的情况下在 Python 中创建 data
。你需要
对象(或其 id
)能够将其添加到自身。 YAML 加载器有类似的问题:
当它解析和构造一个组合(映射或序列)时,它会收集所有
children (key/value pairs resp. elements) 然后构造复合体。所以当复合
在 YAML 中(通过别名)引用自身,锚点的查找需要提供一个真实的,尽管
不完整、构造的 Python 对象(字典、列表,如果是标记对象,则可能是实例
一些 class).
这就是使用创建复合材料的两步过程的原因:您创建一个空对象,它
你交回去,所以如果有必要,可以在 anchor/alias table 中进行参考,
然后在代码的 post yield
部分填写它。
复合材料本身不需要在其中一个中有别名
他们的价值观或元素,但如果他们没有锚,他们可以
在一步过程中构建。但这会导致
不同的构造函数和调用 construct_yaml_map()
的代码
了解这些不同构造的对象。问题
转移,但不会消失,就像你可以创建递归
Python 不同,但仍然需要多个语句。
顺便说一句,这不是 ruamel.yaml
具体的。这段代码在 PyYAML 代码中,而且 AFAIK 仍然如此
ruamel.yaml
的来源。