python 生成器協程運算例項

2022-10-04 20:54:15 字數 3301 閱讀 1553

一、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 列印結果 ...