这是我的代码:
def gen_middle():
def gen_nested():
counter = 0
while True:
yield counter
counter += 1
if counter >= 2:
return 'My special value'
yield from gen_nested()
def main():
iterator = iter(gen_middle())
try:
while True:
value = next(iterator)
print(value)
except StopIteration as exc:
# returned value (with "return") from gen_nested was expected
print(exc.value)
main()
我期望的输出:
0
1
My special value
但我得到了:
0
1
None
对此,我有两个问题。
- 该语句是否不会使用嵌套生成器中的值来
yield from升级异常?StopIteration - 我可以在不更改和函数
'My special value'的代码的情况下获得这个 value()吗?gen_middlegen_nested
所有的高层迭代结构(从
for到yield from)都是自己处理的StopIteration,一个新的异常“出来”了StopIteration,而最里面的迭代器自己抛出的异常value没有出来。value将其传递到整个捕获链可能是合乎逻辑的StopIteration,但显然这是一个罕见的用例,以至于没有人考虑过它。另一方面,如果内部有多个迭代器(例如,多个值序列被粘合在一起,如itertools.chain中),那么哪些值应该被丢弃?如果是后者,那么为什么
return其他生成器的值会消失呢?这里最简单的方法是创建自己的单独异常,从内部抛出它,在最外层处理它,然后
while-next可以将外部异常替换为普通异常for(这样更美观):特别是对于这种情况,如果函数内部恰好有一个
yield from,您可以愚蠢地将其替换为,return以便简单地返回原始生成器: