日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

python asyncio 异步编程---协程

發布時間:2024/7/23 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python asyncio 异步编程---协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、協程

官方描述;
協程是子例程的更一般形式。 子例程可以在某一點進入并在另一點退出。 協程則可以在許多不同的點上進入、退出和恢復。 它們可通過 async def 語句來實現。 參見 PEP 492。

  • 協程不是計算機內部提供的,不像進程、線程,由電腦本身提供,它是由程序員人為創造的, 實現函數異步執行。

  • 協程(Coroutine),也可以被稱為微線程,是一種用戶太內的上下文切換技術,其實就是通過一個線程實現代碼塊相互切換執行。看上去像子程序,但執行過程中,在子程序內部可中斷,然后轉而執行別的子程序,在適當的時候再返回來接著執行。例如:

# 需要python3.7+ import asyncioasync def main():print('hello')await asyncio.sleep(1)print('world')asyncio.run(main())# 打印 "hello",等待 1 秒,再打印 "world"

注意:簡單地調用一個協程并不會使其被調度執行,

直接main() 調用會有問題:

RuntimeWarning: coroutine 'main' was never awaitedmain() 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)【推薦使用】

1.1 greenlet實現協程

# 第三方模塊,因此需要安裝pip install greenlet from greenlet import greenletdef 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

1.2 yield關鍵字

def func1():yield 1yield from func2()yield 2def func2():yield 3yield 4f1 = func1() for item in f1:print(item)# 結果:1 3 2 4

1.3 asynico裝飾器

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

1.4 async & await 關鍵字

import asyncioasync 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))

2. 協程的意義

充分利用線程。在一個線程中如果遇到IO等待時間線程不會一直等待,利用空閑時間再去干點其他事情。

以下載三張圖片為例:

  • 普通方式(同步)下載:
import time import requestsdef 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 = 1for item in url_list:download_image(item, img_name)img_name += 1end = time.time()print(end - start)# 最終時間:7.25s
  • 協程方式(異步)下載:
import aiohttp import asyncio import timeasync 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 异步编程---协程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。