我不确定以下代码中到底发生了什么:
def coroutine():
lst = []
try:
while True:
item = (yield lst)
if item == 3:
raise ValueError
print('append {}'.format(item))
lst.append(item)
except GeneratorExit:
print('GeneratorExit')
crt = coroutine()
next(crt)
print(crt.send(1))
print(crt.send(2))
try:
print(crt.send(3))
except ValueError:
pass
print(crt.send(4))
输出:
append 1
[1]
append 2
[1, 2]
Traceback (most recent call last):
File "D:\Documents and Settings\Brecht\Desktop\crt.py", line 25, in <module>
print(crt.send(4))
StopIteration
当使用调试器逐步执行代码时,在raise ValueError
上,执行跳转到except GeneratorExit:
,但不执行此except子句的主体(不打印'GeneratorExit')。为什么不呢?
除此之外,我不认为在抛出异常之后我可以以任何方式恢复协同程序吗?是否有任何特殊原因不允许这样做?这至少在我的特定用例中是有用的:)
答案 0 :(得分:4)
当您抛出异常时,代码流始终被中断。一旦在其中抛出异常,就无法恢复中断的生成器。
来自PEP 342 (Coroutines via Enhanced Generators):
与
next()
方法一样,send()
方法返回下一个值 由生成器 - 迭代器产生,或者如果是,则引发StopIteration
发电机正常退出,或已经退出。如果发电机 引发未捕获的异常,它会传播到send()
的调用者。
至于调试器跳转到except
行:你刚刚抛出一个异常,解释器正在测试异常是否被该行捕获。因为它只会捕获GeneratorExit
,所以生成器会在此时退出。