上一篇博文介绍的send方法,通过向生成器对象传递参数来实现与生成器对象的交互。本文介绍与生成器对象的另一种方式,即throw方法。它的实现手段是通过向生成器对象在上次被挂起处,抛出一个异常。之后会继续执行生成器对象中后面的语句,直至遇到下一个yield语句返回。如果在生成器对象方法执行完毕后,依然没有遇到yield语句,抛出StopIteration异常。
请看下面的例子
def myGenerator():
value = 1
while True:
yield value
value += 1
gen = myGenerator()
print gen.next()
print gen.next()
print gen.throw(Exception, "Method throw called!")
输出结果为
1
2
Traceback (most recent call last):
File "test.txt", line 11, in <module>
print gen.throw(Exception, "Method throw called!")
File "test.txt", line 4, in myGenerator
yield value
Exception: Method throw called!
代码的最后一句向生成器对象抛出了一个异常。但是,在生成器对象的方法时没有处理该异常的代码,因此异常会被抛出到主方法。
下面的示例中,添加了处理异常的代码
def myGenerator():
value = 1
while True:
try:
yield value
value += 1
except:
value = 1
gen = myGenerator()
print gen.next()
print gen.next()
print gen.throw(Exception, "Method throw called!")
在上面的代码中,加入了一个try-except语句块处理异常。当生成器方法收到异常后,会调到except语句块,将value置为1。因此,代码的输出如下。
1
2
1
Exception RuntimeError: 'generator ignored GeneratorExit' in <generator object myGenerator at 0x00000000028BB900> ignored
上面输出中,第2个1是gen.throw方法的返回值。在执行完该方法后,生成器对象方法的while循环并没有结束,也即是说生成器方法的执行还没有结束。这个时候如果强制结束主程序,会抛出一个RuntimeError。也就是上面输出的第4行。要优雅地关闭主程序,需要用到生成器对象的close方法。后面的博文继续介绍。