转载自:https://blog.csdn.net/hedan2013/article/details/72810653
当一个生成器对象被销毁时,会抛出一个GeneratorExit异常。请看下面的代码。
def myGenerator():
try:
yield 1
except GeneratorExit:
print ("aa")
gen = myGenerator()
print (next(gen))
'''
1
aa
'''
执行过程:
当调用next方法时,会激活生成器,直至遇到生成器方法的yield语句,返回值1。同时,生成器方法被挂起。然后打印1,此时主程序结束,系统会自动产生一个GeneratorExit异常,被生成器对象方法的Except语句块截获。
而GeneratorExit异常产生的时机,是在生成器对象被销毁之前。为了验证这点,请看下面的代码。也就是说,系统在销毁一个生成器之前会先扔给生成器一个GeneratorExit异常
def myGenerator():
try:
yield 1
yield 2
except GeneratorExit:
print ("aa")
gen = myGenerator()
print (next(gen))
del gen#销毁生成器
print ('bb')
'''
1
aa
bb
'''
值得一提的是,GeneratorExit异常只有在生成器对象被激活后,才有可能产生。更确切的说,需要至少调用一次生成器对象的next方法后,系统才会产生GeneratorExit异常。请看下面的代码。
def myGenerator():
try:
yield 1
yield 2
except GeneratorExit:
print ('aa')
gen = myGenerator()
del gen
print ('bb')
'''
bb
'''
在上面的示例中,我们都显式地捕获了GeneratorExit异常。如果该异常没有被显式捕获,生成器对象也不会把该异常向主程序抛出。因为GeneratorExit异常定义的初衷,是方便开发者在生成器对象调用结束后定义一些收尾的工作,如释放资源等。
def myGenerator():
try:
yield 1
yield 2
except NameError:
print ('aa')
gen = myGenerator()
print (next(gen))
del gen
print ('bb')
'''
1
bb
'''
以上就是全部知识点,下面再来分析一个例子:
def myGenerator():
try:
yield 1
yield 2
except GeneratorExit:
print ("aa")
yield
gen = myGenerator()
print (next(gen))
del gen
print ('bb')
'''
1
aa
Exception ignored in: <generator object myGenerator at 0xf54a1a50>
RuntimeError: generator ignored GeneratorExit
bb
'''
del gen这句,系统接到了销毁生成器的命令,在销毁之前,先扔给他一个GeneratorExit异常,这个异常被生成器捕获到,先打印aa,然后遇到了yield,这是生成器抛出RuntimeError异常(生成器正在消亡的过程中当然就不能迭代了),只不过主程序ignore了这个异常了,主程序不受影响接着执行
|