有人知道递归使用时send()如何与生成器一起使用?我希望将值传递给当前的生成器,然后可以将其传递给递归生成器......但似乎情况并非如此?一些示例代码:
def Walk(obj):
recurse = (yield obj)
if not recurse:
print 'stop recurse:', recurse
return
if isinstance(obj, list):
print 'is list:', obj
for item in obj:
print 'item loop:', item
walker = Walk(item)
for x in walker:
print 'item walk:', x
recurse = (yield x)
print 'item walk recurse:', recurse
walker.send(recurse)
root = ['a', ['b.0', ['b.0.0']]]
walker = Walk(root)
for i, x in enumerate(walker):
print i, x
print 'send true'
walker.send(True)
所需的输出应该是每个级别递归的每个值:
0 ['a', ['b.0', ['b.0.0']]]
1 'a'
2 ['b.0', ['b.0.0']]
3 'b.0'
4 ['b.0.0']
5 'b.0.0'
最终发生的事情是:
0 ['a', ['b.0', ['b.0.0']]]
send true
is list: ['a', ['b.0', ['b.0.0']]]
item loop: a
item walk: a
item walk recurse: None
stop recurse: None
看起来recurse = (yield)
的内循环不会等待发送值。或者其他的东西。内部循环recurse
值如何得到None
并不是很清楚;其来电者确实致电send()
。
最终,目标基本上是递归地遍历树结构,但让最顶层的调用者能够指定不何时递归到子结构中。如,
walker = Walk(root)
for node in walker:
if CriteriaMet(node):
walker.send(True)
else:
walker.send(False)
答案 0 :(得分:5)
重要的是要发现send()也会消耗! 来自http://docs.python.org/reference/expressions.html#generator.send:
恢复执行并将值“发送”到生成器函数中。 value参数成为当前yield表达式的结果。 send()方法返回生成器产生的下一个值,或 如果生成器退出而不产生另一个,则引发StopIteration 值。当调用send()来启动生成器时,必须调用它 以None作为参数,因为没有yield表达式 可以收到价值。
以下是您的代码的快速重新处理,以使其按预期输出:
def Walk(obj):
recurse = (yield obj)
if not recurse:
#print 'stop recurse:', recurse
return
if isinstance(obj, list):
#print 'is list:', obj
for item in obj:
#print 'item loop:', item
walker = Walk(item)
recurse = None #first send must be None
while True:
try:
x = walker.send(recurse)
except StopIteration:
break
#print 'item walk:', x
recurse = (yield x)
#print 'item walk recurse:', recurse
root = ['a', ['b.0', ['b.0.0']]]
walker = Walk(root)
i = 0
x = walker.next()
while True:
print i, x
try:
x = walker.send(True)
except StopIteration:
break
i += 1
输出:
0 ['a', ['b.0', ['b.0.0']]]
1 a
2 ['b.0', ['b.0.0']]
3 b.0
4 ['b.0.0']
5 b.0.0