一、yield執行方式
我們定義乙個如下的生成器:
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name))
p = put_on("bigberg")
#輸出g:\python\install\python.exe g:/www.cppcns.compython/untitled/study4/test/double.py
process finished with exit code 0
當我們把乙個函式通過yielwww.cppcns.comd轉換成生成器,直接執行函式是不會出現結果返回的。因為此時函式已經是個生成器了,我們要通過next()來取得值,並且在遇到yield時再次跳出函式。
print(type(p))
#輸出我們新增next()方法:
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield #遇到yield中斷
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name)) #中斷後執行部分
p = put_on("bigberg")
p.__next__()
#輸出hi bigberg, 貨物來了,準備搬到倉庫!
此時函式中斷在 goods = yield 的地方,當我們再次呼叫next()函式時,函式只會執行中斷以後的內容,即上例中的yield下面部分。
我們再新增乙個next():
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name))
p = put_on("bigberg")
p.__next__()
p.__next__()
#輸出hi bigberg, 貨物來了,準備搬到倉庫!
貨物[none]已經被bigberg搬進倉庫了。
我們可以第二次next()執行的是yield下面的部分內容,但是並沒有給goods傳值,所以貨物是 none。
小結:通過yield將函式轉換為生成器,需要使用next()方法才能執行
yield只是保留函式的中斷狀態,再次呼叫next()會執行yield後面的部分
yield如果沒有返回值,會返回乙個none空值
二、send()傳值
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name))
p = put_on("bigberg")
p.__next__()
p.send("瓜子")
#輸出hi bigberg, 貨物來了,準備搬到倉庫!
貨物[瓜子]已經被bigberg搬進倉庫了。
小結:__next__()只是呼叫這個yield,也可以說成是喚醒yield,但是不不會給yield傳值。
send()方法呼叫yield是,能給yield傳值
使用send()函式之前必須使用__next__(),因為先要中斷,當第二次呼叫時,才可傳值。
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name))
p = put_on("bigberg")
p.__next__()
p.send("瓜子")
p.send("花生")
p.send("餅乾")
p.send("牛奶")
#多次呼叫send()
hi bigberg, 貨物來了,準備搬到倉庫!
貨物[瓜子]已經被bigberg搬進倉庫了。
貨物[花生]已經被bigberg搬進倉庫了。
貨物[餅乾]已經被bigberg搬進倉庫了。
貨物[牛奶]已經被bigberg搬進倉庫了。
三、單執行緒實現並行效果(協程)
import time
def put_on(name):
print("hi {}, 貨物來了,準備搬到倉庫!".format(name))
while true:
goods = yield
print("貨物[%s]已經被%s搬進倉庫了。"%(goods,name))
def transfer(name):
p = put_on('a')
p2 = put_on('b')
p.__next__()
p2.__next__()
print("%s將貨物送來了!"%name)
for i in range(5):
time.sleep(1)
print("%s遞過來兩件貨物"%name)
p.send("瓜子")
p2.send("花生")
transfer("bigberg")
#輸出hi a, 貨物來了,準備搬到倉庫!
hi b, 貨物來了,準備搬到倉庫!
bigberg將貨物送來了!
bigberg遞過來兩件貨物
貨物[瓜子]已經被a搬進倉庫了。
貨物[花生]已經被b搬進倉庫了。
bigberg遞過來兩件貨物
貨物[瓜子]已經被a搬進倉庫了。
貨物[花生]已經被b搬進倉程式設計客棧庫了。
bi程式設計客棧gberg遞過來兩件貨物
貨物[瓜子]已經被a搬進倉庫了。
貨物[花生]已經被b搬進倉庫了。
bigberg遞過來兩件貨物
貨物[瓜子]已經被a搬進倉庫了。
貨物[花生]已經被b搬進倉庫了。
bigberg遞過來兩件貨物
貨物[瓜子]已經被a搬進倉庫了。
貨物[花生]已經被b搬進倉庫了。
本文標題: python 生成器協程運算例項
本文位址: /jiaoben/python/202543.html
Python 生成器,協程
生成器可以簡單有效的建立龐大的可迭代物件,而不需要在直接在記憶體中建立儲存整個序列 可以使用生成器推導式或者生成器函式來建立生成器 生成器函式返回資料時使用yield語句,而不是使用return def countdown n print counting down from d n while n...
python迭代器生成器協程
迭代器有兩個基本的方法 iter 和next 把乙個類作為乙個迭代器使用需要在類中實現兩個方法iter 與next stopiteration 異常用於標識迭代的完成 class mylist object def init self self.items def iter self iter my...
Python生成器函式 yield 協程應用
生成器應用 m i for i in range 5 print type m 列印結果 型別 生成器 print next m 列印結果 0 definc for i in range 5 yield i print type inc 列印結果 型別 函式 print type inc 列印結果 ...