python 生成器的GeneratorExit异常

转载自: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了这个异常了,主程序不受影响接着执行

原文地址:https://www.cnblogs.com/saolv/p/9847326.html