Python 中由 yield 實(shí)現(xiàn)異步操作
yield在python中初學(xué)時(shí),覺(jué)得比較難理解。yield的作用:
①返回一個(gè)值、②接收調(diào)用者的參數(shù)
分析下面的代碼:
#!/usr/bin/env python3# -*- coding:utf-8 -*-def consumer(): r = ’’ while True: n = yield r print('[Consumer] n = %d' %n) if not n: return print('[Consumer] consuming %s...' %n) r = ’200 OK’def produce(c): c.send(None) h = 0 while h < 5: h = h + 1 print('[Producer] producing %d...' %h) s = c.send(h) print('[Producer] consumer return: %s' %s) c.close()c = consumer() #創(chuàng)建一個(gè)生成器produce(c) #在該函數(shù)中,調(diào)用生成器的send()方法
結(jié)合程序運(yùn)行過(guò)程,可分析出:
第一步:
在produce(c)函數(shù)中,調(diào)用了c.send(None)啟動(dòng)了生成器,遇到y(tǒng)ield暫停;接著執(zhí)行produce()中接下來(lái)的代碼,從運(yùn)行結(jié)果看,確實(shí)打印出了[Produce] producing 1 … 當(dāng)程序運(yùn)行至c.send(h)時(shí),調(diào)用生成器并且通過(guò)yield傳遞了參數(shù)(h = 1)進(jìn)入consumer()函數(shù)執(zhí)行。
第二步:
yield傳遞參數(shù)(h=1)給consumer()函數(shù)中的n,并接著上一次暫停處往下繼續(xù)執(zhí)行,打印出[Consumer] n = 1,[Consumer] consuming 1… ;在consumer()函數(shù)中此時(shí) r 被賦值為’200 OK’,接著循環(huán)遇到y(tǒng)ield, consumer()函數(shù)又暫停并且返回變量 r 的值,此時(shí)程序又進(jìn)入produce(c)函數(shù)中接著執(zhí)行。
第三步:
produce(c)函數(shù)接著第一步中c.send(h)處,繼續(xù)往下執(zhí)行打印出[Producer] consumer return: 200 OK,并進(jìn)行循環(huán),打印[Producer] producing 2… 后,又調(diào)用c.send(h) 。。。如此循環(huán)回到第一步!
補(bǔ)充知識(shí):python asyncio模型 事件循環(huán)
異步建立在事件循環(huán)上.
簡(jiǎn)單來(lái)說(shuō)事件循環(huán):
1.把要執(zhí)行的函數(shù)放入隊(duì)列
2.取出函數(shù),執(zhí)行
3.看看還要不要繼續(xù)放入此函數(shù)
4.繼續(xù)第一步
一個(gè)簡(jiǎn)單的例子說(shuō)明:
''' 1.yield 掛起當(dāng)前函數(shù). 2.使用調(diào)度器循環(huán) 3.使用next喚醒此函數(shù)繼續(xù)執(zhí)行'''def f1(): for i in range(3): print(’f1 %d’%i) yielddef f2(): for i in range(5): print(’f2 %d’ %i) yielddef f3(): for i in range(10): print(’f3 %d’%i) yield#模擬一個(gè)調(diào)度器task_q = collections.deque((f1(),f2(),f3()))#讓調(diào)度器調(diào)度這些生成器們while task_q: task = task_q.popleft() #彈出首個(gè)生成器 try: next(task) #執(zhí)行,如果沒(méi)有異常證明此生成器還沒(méi)執(zhí)行完成,可以繼續(xù)放入隊(duì)列中 task_q.append(task) #執(zhí)行完成后,把任務(wù)繼續(xù)添加到隊(duì)列中. time.sleep(0.5) except StopIteration as ex: pass
以上這篇Python 中由 yield 實(shí)現(xiàn)異步操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5動(dòng)態(tài)(可拖動(dòng)控件大小)布局控件QSplitter詳細(xì)使用方法與實(shí)例2. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)3. CSS清除浮動(dòng)方法匯總4. 不要在HTML中濫用div5. 父div高度不能自適應(yīng)子div高度的解決方案6. js開(kāi)發(fā)中的頁(yè)面、屏幕、瀏覽器的位置原理(高度寬度)說(shuō)明講解(附圖)7. XML 非法字符(轉(zhuǎn)義字符)8. Python數(shù)據(jù)分析JupyterNotebook3魔法命令詳解及示例9. ASP動(dòng)態(tài)include文件10. vue跳轉(zhuǎn)頁(yè)面常用的幾種方法匯總
