Python生成器(send,close,throw)方法详解
《Python生成器》一節(jié)中,詳細介紹了如何創(chuàng)建一個生成器,以及生成器的基礎用法。本節(jié)將在其基礎上,繼續(xù)講解和生成器有關的一些方法。
Python生成器send()方法
我們知道,通過調用 next() 或者 __next__() 方法,可以實現(xiàn)從外界控制生成器的執(zhí)行。除此之外,通過 send() 方法,還可以向生成器中傳值。
值得一提的是,send() 方法可帶一個參數(shù),也可以不帶任何參數(shù)(用 None 表示)。其中,當使用不帶參數(shù)的 send() 方法時,它和 next() 函數(shù)的功能完全相同。例如:
程序執(zhí)行結果為:
開始執(zhí)行
0
繼續(xù)執(zhí)行
1
注意,雖然 send(None) 的功能是 next() 完全相同,但更推薦使用 next(),不推薦使用 send(None)。
這里重點講解一些帶參數(shù)的 send(value) 的用法,其具備 next() 函數(shù)的部分功能,即將暫停在 yield 語句出的程序繼續(xù)執(zhí)行,但與此同時,該函數(shù)還會將 value 值作為 yield 語句返回值賦值給接收者。
注意,帶參數(shù)的 send(value) 無法啟動執(zhí)行生成器函數(shù)。也就是說,程序中第一次使用生成器調用 next() 或者 send() 函數(shù)時,不能使用帶參數(shù)的 send() 函數(shù)。
舉個例子:
分析一下此程序的執(zhí)行流程:
1) 首先,構建生成器函數(shù),并利用器創(chuàng)建生成器(對象)f 。
2) 使用生成器 f 調用無參的 send() 函數(shù),其功能和 next() 函數(shù)完全相同,因此開始執(zhí)行生成器函數(shù),即執(zhí)行到第一個 yield "hello" 語句,該語句會返回 "hello" 字符串,然后程序停止到此處(注意,此時還未執(zhí)行對 bar_a 的賦值操作)。
3) 下面開始使用生成器 f 調用有參的 send() 函數(shù),首先它會將暫停的程序開啟,同時還會將其參數(shù)“C語言中文網(wǎng)”賦值給當前 yield 語句的接收者,也就是 bar_a 變量。程序一直執(zhí)行完 yield bar_a 再次暫停,因此會輸出“C語言中文網(wǎng)”。
4) 最后依舊是調用有參的 send() 函數(shù),同樣它會啟動餐廳的程序,同時將參數(shù)“http://c.biancheng.net”傳給 bar_b,然后執(zhí)行完 yield bar_b 后(輸出 http://c.biancheng.net),程序執(zhí)行再次暫停。
因此,該程序的執(zhí)行結果為:
hello
C語言中文網(wǎng)
http://c.biancheng.net
Python生成器close()方法
當程序在生成器函數(shù)中遇到 yield 語句暫停運行時,此時如果調用 close() 方法,會阻止生成器函數(shù)繼續(xù)執(zhí)行,該函數(shù)會在程序停止運行的位置拋出 GeneratorExit 異常。
舉個例子:
程序執(zhí)行結果為:
1
捕獲到 GeneratorExit
注意,雖然通過捕獲?GeneratorExit 異常,可以繼續(xù)執(zhí)行生成器函數(shù)中剩余的代碼,帶這部分代碼中不能再包含 yield 語句,否則程序會拋出 RuntimeError 異常。例如:
程序執(zhí)行結果為:
1
捕獲到 GeneratorExit Traceback (most recent call last):
? File "D:\python3.6\1.py", line 10, in <module>
??? f.close()
RuntimeError: generator ignored GeneratorExit
另外,生成器函數(shù)一旦使用 close() 函數(shù)停止運行,后續(xù)將無法再調用 next() 函數(shù)或者 __next__() 方法啟動執(zhí)行,否則會拋出 StopIteration 異常。例如:
程序執(zhí)行結果為:
c.biancheng.net
Traceback (most recent call last):
? File "D:\python3.6\1.py", line 8, in <module>
??? next(f) #原本應輸出"生成器停止執(zhí)行"
StopIteration
Python生成器throw()方法
生成器 throw() 方法的功能是,在生成器函數(shù)執(zhí)行暫停處,拋出一個指定的異常,之后程序會繼續(xù)執(zhí)行生成器函數(shù)中后續(xù)的代碼,直到遇到下一個 yield 語句。需要注意的是,如果到剩余代碼執(zhí)行完畢沒有遇到下一個 yield 語句,則程序會拋出 StopIteration 異常。
舉個例子:
程序執(zhí)行結果為:
1
捕獲到 ValueError
Traceback (most recent call last):
? File "D:\python3.6\1.py", line 9, in <module>
??? f.throw(ValueError)
StopIteration
顯然,一開始生成器函數(shù)在 yield 1 處暫停執(zhí)行,當執(zhí)行 throw() 方法時,它會先拋出 ValueError 異常,然后繼續(xù)執(zhí)行后續(xù)代碼找到下一個 yield 語句,該程序中由于后續(xù)不再有 yield 語句,因此程序執(zhí)行到最后,會拋出一個 StopIteration 異常。
總結
以上是生活随笔為你收集整理的Python生成器(send,close,throw)方法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python协程(真才实学,想学的进来)
- 下一篇: coroutine协程详解