轉載自: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了這個異常了,主程序不受影響接着執行
