1. 程式人生 > >python3-yield生成器

python3-yield生成器

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