python 生成器協(xié)程運(yùn)算實(shí)例
一、yield運(yùn)行方式
我們定義一個如下的生成器:
def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(goods,name)) p = put_on("bigberg") #輸出 G:\python\install\python.exe G:/python/untitled/study4/test/double.py Process finished with exit code 0
當(dāng)我們把一個函數(shù)通過yield轉(zhuǎn)換成生成器,直接運(yùn)行函數(shù)是不會出現(xiàn)結(jié)果返回的。因?yàn)榇藭r函數(shù)已經(jīng)是個生成器了,我們要通過next()來取得值,并且在遇到y(tǒng)ield時再次跳出函數(shù)。
print(type(p)) #輸出 <class 'generator'>
我們添加next()方法:
def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield #遇到y(tǒng)ield中斷 print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(goods,name)) #中斷后運(yùn)行部分 p = put_on("bigberg") p.__next__() #輸出 Hi bigberg, 貨物來了,準(zhǔn)備搬到倉庫!
此時函數(shù)中斷在 goods = yield 的地方,當(dāng)我們再次調(diào)用next()函數(shù)時,函數(shù)只會運(yùn)行中斷以后的內(nèi)容,即上例中的yield下面部分。
我們再添加一個next():
def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(goods,name)) p = put_on("bigberg") p.__next__() p.__next__() #輸出 Hi bigberg, 貨物來了,準(zhǔn)備搬到倉庫! 貨物[None]已經(jīng)被bigberg搬進(jìn)倉庫了。
我們可以第二次next()運(yùn)行的是yield下面的部分內(nèi)容,但是并沒有給goods傳值,所以貨物是 None。
小結(jié):
通過yield將函數(shù)轉(zhuǎn)換為生成器,需要使用next()方法才能運(yùn)行
yield只是保留函數(shù)的中斷狀態(tài),再次調(diào)用next()會執(zhí)行yield后面的部分
yield如果沒有返回值,會返回一個None空值
二、send()傳值
def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(goods,name)) p = put_on("bigberg") p.__next__() p.send("瓜子") #輸出 Hi bigberg, 貨物來了,準(zhǔn)備搬到倉庫! 貨物[瓜子]已經(jīng)被bigberg搬進(jìn)倉庫了。
小結(jié):
__next__()只是調(diào)用這個yield,也可以說成是喚醒yield,但是不不會給yield傳值。
send()方法調(diào)用yield是,能給yield傳值
使用send()函數(shù)之前必須使用__next__(),因?yàn)橄纫袛?,?dāng)?shù)诙握{(diào)用時,才可傳值。
def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(goods,name)) p = put_on("bigberg") p.__next__() p.send("瓜子") p.send("花生") p.send("餅干") p.send("牛奶") #多次調(diào)用send() Hi bigberg, 貨物來了,準(zhǔn)備搬到倉庫! 貨物[瓜子]已經(jīng)被bigberg搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被bigberg搬進(jìn)倉庫了。 貨物[餅干]已經(jīng)被bigberg搬進(jìn)倉庫了。 貨物[牛奶]已經(jīng)被bigberg搬進(jìn)倉庫了。
三、單線程實(shí)現(xiàn)并行效果(協(xié)程)
import time def put_on(name): print("Hi {}, 貨物來了,準(zhǔn)備搬到倉庫!".format(name)) while True: goods = yield print("貨物[%s]已經(jīng)被%s搬進(jìn)倉庫了。"%(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, 貨物來了,準(zhǔn)備搬到倉庫! Hi B, 貨物來了,準(zhǔn)備搬到倉庫! bigberg將貨物送來了! bigberg遞過來兩件貨物 貨物[瓜子]已經(jīng)被A搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被B搬進(jìn)倉庫了。 bigberg遞過來兩件貨物 貨物[瓜子]已經(jīng)被A搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被B搬進(jìn)倉庫了。 bigberg遞過來兩件貨物 貨物[瓜子]已經(jīng)被A搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被B搬進(jìn)倉庫了。 bigberg遞過來兩件貨物 貨物[瓜子]已經(jīng)被A搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被B搬進(jìn)倉庫了。 bigberg遞過來兩件貨物 貨物[瓜子]已經(jīng)被A搬進(jìn)倉庫了。 貨物[花生]已經(jīng)被B搬進(jìn)倉庫了。
以上這篇python 生成器協(xié)程運(yùn)算實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Pycharm在創(chuàng)建py文件時,自動添加文件頭注釋的實(shí)例
今天小編就為大家分享一篇Pycharm在創(chuàng)建py文件時,自動添加文件頭注釋的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05Python Django教程之實(shí)現(xiàn)待辦事項(xiàng)應(yīng)用程序
Django是一個基于Python Web框架的高級Web框架,允許快速開發(fā)和干凈,務(wù)實(shí)的設(shè)計。本文將創(chuàng)建一個待辦事項(xiàng)應(yīng)用程序,以了解Django的基礎(chǔ)知識,感興趣的可以嘗試一下2022-10-10PyQt中使用QtSql連接MySql數(shù)據(jù)庫的方法
這篇文章主要介紹了PyQt中使用QtSql連接MySql數(shù)據(jù)庫的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07通過Python收集匯聚MySQL 表信息的實(shí)例詳解
這篇文章主要介紹了通過Python收集匯聚MySQL 表信息的實(shí)例代碼,核心代碼是創(chuàng)建保存數(shù)據(jù)的腳本,收集的功能腳本,代碼簡單明了,需要的朋友可以參考下2021-10-10Python高級應(yīng)用探索之元編程和并發(fā)編程詳解
Python作為一種簡單易用且功能強(qiáng)大的編程語言,廣泛應(yīng)用于各個領(lǐng)域,本文主要來和大家一起探索一下Python中的優(yōu)化技巧、元編程和并發(fā)編程,希望對大家有所幫助2023-11-11