歡迎您光臨本站 註冊首頁

Python 中由 yield 實現異步操作

←手機掃碼閱讀     f2h0b53ohn @ 2020-05-04 , reply:0

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


[f2h0b53ohn ] Python 中由 yield 實現異步操作已經有247次圍觀

http://coctec.com/docs/python/shhow-post-232874.html