您好,登錄后才能下訂單哦!
小編給大家分享一下Python生成器和基于生成器的協程,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
Generator
1.生成器就是可以生成值的函數
2.當一個函數里有了 yield
關鍵字就成了生成器
3.生成器可以掛起執行并且保持當前執行的狀態
代碼示例:
def simple_gen(): yield 'hello' yield 'world' gen = simple_gen() print(type(gen)) # 'generator' object print(next(gen)) # 'hello' print(next(gen)) # 'world'
Python3
之前沒有原生協程,只有基于生成器的協程
1.pep
342(Coroutines via Enhanced Generators
)增強生成器功能
2.生成器可能通過 yield
暫停執行和產出數據
3.同時支持send()
向生成器發送數據和throw()
向生成器拋出異常
Generator Based Corouteine代碼示例:
def coro(): hello = yield 'hello' # yield 關鍵字在 = 右邊作為表達式,可以被 send 值 yield hello c = coro() # 輸出 'hello', 這里調用 next 產出第一個值 'hello',之后函數暫停 print(next(c)) # 再次調用 send 發送值,此時 hello 變量賦值為 'world',然后 yield 產出 hello 變量的值 'world' print(c.send('world')) # 之后協程結束,后續再 send 值會拋出異常 StopIteration
運行結果:
協程注意點
1.協程需要使用send(None)
或者next(coroutine)
來預激(prime
)才能啟動
2.在yield
處協程會暫停執行
3.單獨的yield value
會產出值給調用方
4.可以通過 coroutine.send(value)
來給協程發送值,發送的值會賦值給 yield
表達式左邊的變量value = yield
5.協程執行完成后(沒有遇到下一個yield
語句)會拋出StopIteration
異常
避免每次都要用 send
預激它
from functools import wraps def coroutine(func): # 這樣就不用每次都用 send(None) 啟動了 “”“裝飾器:向前執行到一個 `yield` 表達式,預激 `func` ”“” @wrops(func) def primer(*args, **kwargs): # 1 gen = func(*args, **kwargs) # 2 next(gen) # 3 return gen # 4 return primer
python3.5引入 async/await支持原生協程(native coroutine)
import asyncio import datetime import random async def display_date(num, loop): end_time = loop.time() + 50.0 while True: print('Loop: {} Time: {}'.format(num, datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(random.randint(0, 5)) loop = asyncio.get_event_loop() asyncio.ensure_future(display_date(1, loop)) asyncio.ensure_future(display_date(2, loop)) loop.run_forever()
看完了這篇文章,相信你對“Python生成器和基于生成器的協程”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。