本篇內容主要講解“Python協程asyncio的作用是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python協程asyncio的作用是什么”吧!
官方描述;
協程是子例程的更一般形式。 子例程可以在某一點進入并在另一點退出。 協程則可以在許多不同的點上進入、退出和恢復。 它們可通過 async def 語句來實現。 參見 PEP 492。
協程不是計算機內部提供的,不像進程、線程,由電腦本身提供,它是由程序員人為創造的, 實現函數異步執行。
協程(Coroutine),也可以被稱為微線程,是一種用戶太內的上下文切換技術,其實就是通過一個線程實現代碼塊相互切換執行??瓷先ハ褡映绦?,但執行過程中,在子程序內部可中斷,然后轉而執行別的子程序,在適當的時候再返回來接著執行。例如:
# 需要python3.7+ import asyncio async def main(): print('hello') await asyncio.sleep(1) print('world') asyncio.run(main()) # 打印 "hello",等待 1 秒,再打印 "world"
注意:簡單地調用一個協程并不會使其被調度執行,
直接main() 調用會有問題:
RuntimeWarning: coroutine 'main' was never awaited main() RuntimeWarning: Enable tracemalloc to get the object allocation traceback
def func1(): print(1) ... print(2) def func2(): print(3) ... print(4) func1() func2() # 結果:1 2 3 4
實現協程的方法:
greenlet,早期模塊【不建議使用】
yield關鍵字,它是python的生成器,具有保存狀態,切換到其他函數去執行,再切換回原函數的功能。
asyncio裝飾器(python3.4引入)
async、await 關鍵字(python3.5)【推薦使用】
# 第三方模塊,因此需要安裝 pip install greenlet
from greenlet import greenlet def func1(): print(1) gr2.switch() print(2) gr2.switch() def func2(): print(3) gr1.switch() print(4) gr1 = greenlet(func1) gr2 = greenlet(func2) gr1.switch() # 結果:1 3 2 4
def func1(): yield 1 yield from func2() yield 2 def func2(): yield 3 yield 4 f1 = func1() for item in f1: print(item) # 結果:1 3 2 4
python3.4 及之后版本支持
DeprecationWarning: “@coroutine” decorator is deprecated since Python 3.8, use “async def”
翻譯:@coroutine"裝飾器自Python 3.8起已棄用,請使用"async def"代替
所以這個也不支持。
import asyncio @asyncio.coroutine def func1(): print(1) yield from asyncio.sleep(2) # 遇到IO耗時操作,自動切換到tasks中其他任務,比如:網絡IO,下載圖片 print(2) @asyncio.coroutine def func2(): print(3) yield from asyncio.sleep(2) # 遇到IO耗時操作,自動切換到tasks中其他任務,比如:網絡IO,下載圖片 print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) # 結果: 1 3 2 4
import asyncio async def func1(): print(1) await asyncio.sleep(2) # 遇到IO耗時操作,自動切換到tasks中其他任務,比如:網絡IO,下載圖片 print(2) async def func2(): print(3) await asyncio.sleep(2) # 遇到IO耗時操作,自動切換到tasks中其他任務,比如:網絡IO,下載圖片 print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks))
充分利用線程。在一個線程中如果遇到IO等待時間線程不會一直等待,利用空閑時間再去干點其他事情。
以下載三張圖片為例:
普通方式(同步)下載:
import time import requests def download_image(url, img_name): print("開始下載:", url) # 發送網絡請求,下載圖片 response = requests.get(url) print("下載完成") # 圖片保存到本地文件 file_name = str(img_name) + '.png' with open(file_name, mode='wb') as file: file.write(response.content) if __name__ == '__main__': start = time.time() url_list = [ 'https://tse4-mm.cn.bing.net/th/id/OIP.866vRxQ8QvyDsrUuXiu7qwHaNK?w=182&h=324&c=7&o=5&pid=1.7', 'https://tse2-mm.cn.bing.net/th/id/OIP.HUcWtoYPG-z2pu4ityajbAHaKQ?w=182&h=252&c=7&o=5&pid=1.7', 'https://tse2-mm.cn.bing.net/th/id/OIP.MvncR0-Pt9hVxKTdrvD9dAHaNK?w=182&h=324&c=7&o=5&pid=1.7', 'https://tse1-mm.cn.bing.net/th/id/OIP._nGloaeMWbL7NB7Lp6SnXQHaLH?w=182&h=273&c=7&o=5&pid=1.7', ] img_name = 1 for item in url_list: download_image(item, img_name) img_name += 1 end = time.time() print(end - start) # 最終時間:7.25s
協程方式(異步)下載:
import aiohttp import asyncio import time async def fetch(session, url): print("發送請求:", url) async with session.get(url, verify_ssl=False) as response: content = await response.content.read() file_name = url.rsplit('_')[-1] # print(file_name) with open(file_name, mode='wb') as file_object: file_object.write(content) print("下載完成") async def main(): async with aiohttp.ClientSession() as session: url_list = [ 'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg', 'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg', 'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg', 'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg', ] tasks = [asyncio.ensure_future(fetch(session, url)) for url in url_list] await asyncio.wait(tasks) if __name__ == '__main__': start = time.time() asyncio.get_event_loop().run_until_complete(main()) end = time.time() print(end - start) # 結果:0.05s
到此,相信大家對“Python協程asyncio的作用是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。