我有一个对象的树形结构。我需要迭代所有叶子节点中的所有项(“values”)。为此,我目前使用生成器方法,如下所示:
现在,
这个解决方案存在问题。我一直在广泛使用 itertools.tee (和 chain) 轻松保存迭代器的状态以防需要回溯。我希望这些也能用于协程,但不幸的是,没有这样的运气。目前我正在考虑一些替代方案:
- 让生成器产生接受外部参数的函数(闭包) - 编写自定义类来模拟具有保存状态功能的协程
第一个选项似乎最具吸引力。但也许还有更好的选择?
class Node(object):
def __init__(self):
self.items = [Leaf(1), Leaf(2), Leaf(3)]
def values(self):
for item in self.items:
for value in item.values():
yield value
class Leaf(object):
def __init__(self, value):
self.value = value
def values(self):
for i in range(2):
yield self.value
n = Node()
for value in n.values():
print(value)
这将打印:
1
1
2
2
3
3
现在,
Leaf
返回的值将取决于外部参数。我考虑使用协程来将此参数传递到叶子节点:import itertools
class Node2(object):
def __init__(self):
self.items = [Leaf2(1), Leaf2(2), Leaf2(3)]
def values(self):
parameter = yield
for item in self.items:
item_values = item.values()
next(item_values) # advance to first yield
try:
while True:
parameter = (yield item_values.send(parameter))
except StopIteration:
pass
class Leaf2(object):
def __init__(self, value):
self.value = value
def values(self):
parameter = yield
try:
for i in range(2):
parameter = (yield '{}{}'.format(self.value, parameter))
except StopIteration:
pass
n2 = Node2()
values2 = n2.values()
next(values2) # advance to first yield
try:
for i in itertools.count(ord('A')):
print(values2.send(chr(i)))
except StopIteration:
pass
这段代码并不美观,但它能正常工作。它会打印出:
1A
1B
2C
2D
3E
3F
这个解决方案存在问题。我一直在广泛使用 itertools.tee (和 chain) 轻松保存迭代器的状态以防需要回溯。我希望这些也能用于协程,但不幸的是,没有这样的运气。目前我正在考虑一些替代方案:
- 让生成器产生接受外部参数的函数(闭包) - 编写自定义类来模拟具有保存状态功能的协程
第一个选项似乎最具吸引力。但也许还有更好的选择?
一些背景信息:我正在RinohType中使用这个结构,其中树由MixedStyledText
(节点)和SingleStyledText
(叶子)对象组成。 spans()
方法返回SingleStyledText
实例。后者可以依赖于外部参数。例如,它们被渲染到的页面编号。目前将其视为特殊情况。