Python 中由 yield 實現非同步操作
阿新 • • 發佈:2020-05-06
yield在python中初學時,覺得比較難理解。yield的作用:
①返回一個值、②接收呼叫者的引數
分析下面的程式碼:
#!/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() #建立一個生成器 produce(c) #在該函式中,呼叫生成器的send()方法
結合程式執行過程,可分析出:
第一步:
在produce(c)函式中,呼叫了c.send(None)啟動了生成器,遇到yield暫停;接著執行produce()中接下來的程式碼,從執行結果看,確實打印出了[Produce] producing 1 … 當程式執行至c.send(h)時,呼叫生成器並且通過yield傳遞了引數(h = 1)進入consumer()函式執行。
第二步:
yield傳遞引數(h=1)給consumer()函式中的n,並接著上一次暫停處往下繼續執行,打印出[Consumer] n = 1,[Consumer] consuming 1… ;在consumer()函式中此時 r 被賦值為'200 OK',接著迴圈遇到yield, consumer()函式又暫停並且返回變數 r 的值,此時程式又進入produce(c)函式中接著執行。
第三步:
produce(c)函式接著第一步中c.send(h)處,繼續往下執行打印出[Producer] consumer return: 200 OK,並進行迴圈,列印[Producer] producing 2… 後,又呼叫c.send(h) 。。。如此迴圈回到第一步!
補充知識:python asyncio模型 事件迴圈
非同步建立在事件迴圈上.
簡單來說事件迴圈:
1.把要執行的函式放入佇列
2.取出函式,執行
3.看看還要不要繼續放入此函式
4.繼續第一步
一個簡單的例子說明:
""" 1.yield 掛起當前函式. 2.使用排程器迴圈 3.使用next喚醒此函式繼續執行 """ def f1(): for i in range(3): print('f1 %d'%i) yield def f2(): for i in range(5): print('f2 %d' %i) yield def f3(): for i in range(10): print('f3 %d'%i) yield #模擬一個排程器 task_q = collections.deque((f1(),f2(),f3())) #讓排程器排程這些生成器們 while task_q: task = task_q.popleft() #彈出首個生成器 try: next(task) #執行,如果沒有異常證明此生成器還沒執行完成,可以繼續放入佇列中 task_q.append(task) #執行完成後,把任務繼續新增到佇列中. time.sleep(0.5) except StopIteration as ex: pass
以上這篇Python 中由 yield 實現非同步操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。