python3-yield生成器
阿新 • • 發佈:2018-11-04
jield的本質是將函式變成一個生成器和迭代器
【例】
import types from collections import Iterable #from inspect import isgeneratorfunction def helloYield(n): print("HHHA:0====>") for i in range(n): print("HHHA:0.1====>") n = yield i print("HHHA:0.2====>", n) print("HHHA:1====>") print("HHHH:0========>") yieldReval = helloYield(5) print("HHHH:1========>") print("yieldReval is GeneratorType ? : ", isinstance(yieldReval, types.GeneratorType)) print("yieldReval is Iterable ? : ", isinstance(yieldReval, Iterable)) #print("Iterable ? : ", isgeneratorfunction(yieldObj)) print("HHHH:2========>") for i in yieldReval: print("HHHB:0====>i=", i) if i == 1: print("HHHB:0.1====>send(99)") yieldReval.send(99)
輸出:
HHHH:0========> HHHH:1========> //yieldObj = helloYield(5) //並未呼叫函式helloYield() yieldReval is GeneratorType ? : True //返回值是一個生成器 yieldReval is Iterable ? : True //返回值是一個迭代器 HHHH:2========> //開始用for 來遍歷生成器 HHHA:0====> //for 迴圈暫停,helloYield()函式開始執行, HHHA:0.1====> //直到遇到“yield"時,helloYield()函式暫停,並將yield後面的值返回給for HHHB:0====>i= 0 //for 恢復執行,直到本次迴圈結束或者yieldReval.send()時暫停 HHHA:0.2====> None //helloYield()函式恢復執行... HHHA:0.1====> //直到再遇到yield ... HHHB:0====>i= 1 HHHB:0.1====>send(99) //for向helloYield傳送數值 HHHA:0.2====> 99 //helloYield()收到數值 HHHA:0.1====> HHHA:0.2====> None //(重複上面的過程)... HHHA:0.1====> HHHB:0====>i= 3 HHHA:0.2====> None HHHA:0.1====> HHHB:0====>i= 4 HHHA:0.2====> None //直到helloYield()再也無法遇到yield,將丟擲StopIteration異常 HHHA:1====> //for 迴圈遇到StopIteration異常時結果整個迴圈體
要點:
1.包含“yield”的函式不再是普通函式,而是一個生成器+迭代器+函式;
2.訪問jieldReval時,原執行處的程式碼與helloYield()函式的程式碼“交叉執行”;
3.單執行緒!(兩處程式碼“同時”執行,沒有既沒有執行緒切換也沒有加鎖——這是yield最特別的地方);
參考:https://www.liaoxuefeng.com/article/001373892916170b88313a39f294309970ad53fc6851243000