您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“python終止協(xié)程和異常處理的方法是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“python終止協(xié)程和異常處理的方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
協(xié)程中未處理的異常會(huì)向上冒泡,傳給 next 函數(shù)或 send 方法的調(diào)用方(即觸發(fā)協(xié)程的對(duì) 象)。
""" 預(yù)激協(xié)程的裝飾器 """ from inspect import getgeneratorstate from functools import wraps def coroutine(func): """裝飾器:向前執(zhí)行到第一個(gè)`yield`表達(dá)式,預(yù)激`func`""" # 把被裝飾的生成器函數(shù)替換成這里的 primer 函數(shù); # 調(diào)用 primer 函數(shù)時(shí),返回預(yù)激后的 生成器。 @wraps(func) def primer(*args, **kwargs): # 調(diào)用被裝飾的函數(shù),獲取生成器對(duì)象。 gen = func(*args, **kwargs) # 預(yù)激生成器。 next(gen) # 返回生成器。 return gen return primer @coroutine def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total / count if __name__ == '__main__': coro_avg = averager() # print(getgeneratorstate(coro_avg)) print(coro_avg.send(10)) print(coro_avg.send(30)) # 發(fā)送的值不是數(shù)字,導(dǎo)致協(xié)程內(nèi)部有異常拋出。 print(coro_avg.send('spam')) # 由于在協(xié)程內(nèi)沒有處理異常,協(xié)程會(huì)終止。 # 如果試圖重新激活協(xié)程,會(huì)拋出 StopIteration 異常。 print(coro_avg.send(60))
上面示例,暗示了終止協(xié)程的一種方式:發(fā)送某個(gè)哨符值,讓協(xié)程退出。內(nèi)置的 None 和 Ellipsis 等常量經(jīng)常用作哨符值。Ellipsis 的優(yōu)點(diǎn)是,數(shù)據(jù)流中不太常有這個(gè)值。我還見 過(guò)有人把 StopIteration 類(類本身,而不是實(shí)例,也不拋出)作為哨符值;也就是說(shuō), 是像這樣使用的:my_coro.send(StopIteration)。
從 Python 2.5 開始,客戶代碼可以在生成器對(duì)象上調(diào)用兩個(gè)方法,顯式地把異常發(fā)給協(xié)程。
這兩個(gè)方法是 throw 和 close。
generator.throw(exc_type[, exc_value[, traceback]])
致使生成器在暫停的 yield 表達(dá)式處拋出指定的異常。
如果生成器處理了拋出的異常,代碼會(huì)向前執(zhí)行到下一個(gè) yield 表達(dá)式,而產(chǎn)出的值會(huì)成為調(diào)用 generator.throw 方法 得到的返回值。
如果生成器沒有處理拋出的異常,異常會(huì)向上冒泡,傳到調(diào)用方的上下 文中。
generator.close()
致使生成器在暫停的yield 表達(dá)式處拋出GeneratorExit 異常。
如果生成器沒有處 理這個(gè)異常,或者拋出了StopIteration 異常(通常是指運(yùn)行到結(jié)尾),調(diào)用方不會(huì) 報(bào)錯(cuò)。
如果收到GeneratorExit 異常,生成器一定不能產(chǎn)出值,否則解釋器會(huì)拋出 RuntimeError 異常。
生成器拋出的其他異常會(huì)向上冒泡,傳給調(diào)用方。
如何使用 close 和 throw 方法控制協(xié)程:
""" 學(xué)習(xí)在協(xié)程中處理異常的測(cè)試代碼 """ from inspect import getgeneratorstate class DemoException(Exception): """為這次演示定義的異常類型。""" def demo_exc_handling(): print('-> coroutine started') try: while True: try: x = yield # 特別處理 DemoException 異常 except DemoException: print('*** DemoException handled. Continuing...') # 如果沒有異常,那么顯示接收到的值。 else: print('-> coroutine received: {!r}'.format(x)) finally: # 如果不管協(xié)程如何結(jié)束都想做些清理工作, # 要把協(xié)程定義體中相關(guān)的代碼放入try/ finally 塊中 print('-> coroutine ending') if __name__ == '__main__': exc_coro = demo_exc_handling() next(exc_coro) exc_coro.send(11) exc_coro.send(22) # 激活和關(guān)閉 demo_exc_handling,沒有異常 # exc_coro.close() # 如果把 DemoException 異常傳入 demo_exc_handling 協(xié)程, # 它會(huì)處理,然后繼續(xù)運(yùn)行 # exc_coro.throw(DemoException) # exc_coro.send(33) # 如果無(wú)法處理傳入的異常,協(xié)程會(huì)終止 exc_coro.throw(ZeroDivisionError) print(getgeneratorstate(exc_coro))
讀到這里,這篇“python終止協(xié)程和異常處理的方法是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。