当前位置: 首页 > news >正文

网络通信与并发编程(九)asyncio

asyncio

文章目录

  • asyncio
  • 一、asyncio的基本使用
  • 二、asyncio的并发
  • 三、异步迭代器于异步上下文管理器
    • 3.1异步迭代器
    • 3.2异步上下文管理器
  • 四、使用asyncio异步访问百度

一、asyncio的基本使用

asyncio模块是python的异步协程模块,使用该模块时python解释器的版本应大于等于3.5。

使用asyncio实现循环调用协程函数:

import asyncio#协程函数是协程中需要执行的任务,需要使用如下的定义方式
async def f():print('协程函数的代码')def main():res=f()#执行协程函数需要采用以下的循环调用方式asyncio.get_event_loop().run_until_complete(res)#或者可以写为,但是解释器版本需大于等于3.7#asyncio.run(res)main()

await的使用方法:
await函数只能用于协程函数内部,当协程函数遇到I/O操作时使用await可以执行其他并发任务,此时该协程任务会被挂起,当I/O执行完以后再继续执行该协程任务。
另外需要注意的是await只能等待非阻塞的任务,例如想要使用await完成爬虫任务需要将常使用的requests库替换为aiohttp库,因为requests的I/O操作会阻塞线程从而协程无法完成并发操作,而aiohttp允许异步爬取多个网站信息。

import asyncioasync def other_task(n):print('start%s'%n)#模拟I/O操作,在此期间协程会执行并发的其他任务await asyncio.sleep(n)print('end%s'%n)async def f():#并发执行两个协程函数#asyncio.gather返回执行协程函数返回值的列表await asyncio.gather(other_task(4),other_task(6))def main():asyncio.run(f())main()

二、asyncio的并发

asyncio并发执行任务有两个函数asyncio.gather和asyncio.wait(python3.11版本后弃用,可以改用asyncio.TaskGroup()类)

asyncio.gather(*aws,return_exceptions)有两个参数,*aws可传入多个需执行的任务;return_exceptions默认为False,此时并发任务报错会直接中断其他任务并抛出错误,return_exceptions=True时并发任务报错其他任务正常执行,报错信息传入返回值中。

asyncio.wait(aws,timeout,return_when),aws传入一个可迭代对象,包含要执行的协程任务;
timeout=None是一个可选参数,用于指定等待的最长时间(以秒为单位)。如果超时时间到达而任务还未完成,则协程函数会取消。如果设置为 None,则会等待直到所有任务完成;return_when=ALL_COMPLETED:这是一个可选参数,用于指定何时返回。它必须为以下常数之一:

  • asyncio.FIRST_COMPLETED:如果有任何一个任务完成,则立即返回。
  • asyncio.FIRST_EXCEPTION:如果有任何一个任务抛出异常,则立即返回。
  • asyncio.ALL_COMPLETED:只有当所有任务都完成时才返回。

asyncio.wait 返回一个集合:(done, pending)。done 包含所有已完成或抛出异常的任务,而 pending 包含所有未完成的任务。

import asyncioasync def other_task(n):print('start%s'%n)#模拟I/O操作,在此期间协程会执行并发的其他任务await asyncio.sleep(n)print('end%s'%n)async def f():#并发执行两个协程函数#asyncio.gather返回执行协程函数返回值的列表done,pending=await asyncio.wait([asyncio.create_task(other_task(6)),asyncio.create_task(other_task(4))],timeout=5)print(done)print(pending)def main():asyncio.run(f())main()

三、异步迭代器于异步上下文管理器

3.1异步迭代器

异步迭代器与一般的迭代器使用方法相同,异步迭代器对象需要包含__ater__()和__anext__(),而async for可以用来遍历异步可迭代对象。

import asyncioclass Read():def __init__(self):self.c=0self.stop=Falseasync def add(self):self.c+=1if self.c>100:self.stop=Truereturn self.cdef __aiter__(self):return selfasync def __anext__(self):val=await self.add()if not self.stop:return valraise StopAsyncIterationasync def main():async for i in Read():print(i)asyncio.run(main())

3.2异步上下文管理器

async with的用法和with相同,async with可以与asyncontextmanager装饰器连用,使用async with时会调用__aenter__()方法,退出async with代码块时会调用__aexit__()方法

from contextlib import asynccontextmanager
import asyncio@asynccontextmanager
#进入with块时代码运行至yield处,退出with块时运行yield后代码
async def t(i):print('enter')await asyncio.sleep(i)yield 'done'print('exit')async def main():async with t(1) as f:print(f)asyncio.run(main())
import asyncioclass MytTest:def __init__(self,n):self.n=nasync def do(self):await asyncio.sleep(self.n)return 'done'async def __aenter__(self):print('enter')#with块的返回值mreturn selfasync def __aexit__(self,exc_type,exc_value,exc_tb):print('exit')await asyncio.sleep(self.n)async def main():async with MytTest(2) as m:res=await m.do()print(res)asyncio.run(main())

四、使用asyncio异步访问百度

import asyncio,aiohttpasync def connect(session,n,url):async with session.get(url=url) as response:if response.status==200:print('%s连接成功'%n)else:print('连接失败')async def main():l = []async with aiohttp.ClientSession() as session:for i in range(100):l.append(asyncio.create_task(connect(session,i, 'https://www.baidu.com')))  # 修正这里await asyncio.gather(*l)loop = asyncio.get_event_loop()
loop.run_until_complete(main())

http://www.mrgr.cn/news/64341.html

相关文章:

  • 扫描电镜的超低温冷冻制样及传输技术(Cryo-SEM)
  • leet 3175. 找到连续赢 K 场比赛的第一位玩家
  • 鸿蒙ArkTS中的面向对象编程
  • leetcode hot100【LeetCode 322. 零钱兑换】java实现
  • [RoarCTF 2019]Easy Calc 1
  • unity3d————三角函数练习题
  • 【ReactPress】一款基于React的开源博客CMS内容管理平台—ReactPress
  • Python Turtle模块详解与使用教程
  • ITK-膨胀
  • ‌频率和波长之间存在反比关系‌
  • 算法妙妙屋-------1.递归的深邃回响:C++ 算法世界的优雅之旅
  • (八)JavaWeb后端开发——Tomcat
  • 超好用的视频剪辑软件分享:10款剪辑软件推荐
  • UE5 猎户座漂浮小岛 06 角色
  • opengl学习-2vao和vbo(通义千问的例子)
  • 4.2.4 根据DTS完成timer初始化
  • 491.递增子序列
  • 爬虫学习2
  • LeetCode25:K个一组翻转链表
  • 【面渣逆袭】JavaSE笔记
  • Gin入门笔记
  • 深度学习基础—序列采样
  • 网络:ARP的具体过程和ARP欺骗
  • MATLAB中sort函数用法
  • 【Kaggle | Pandas】练习6:重命名和组合
  • cn.afterturn.easypoi.exception.excel.ExcelExportException: Excel导出错误 -> 修正过程。