找回密码
 会员注册
查看: 36|回复: 0

详细分析python中的async和await(附Demo)

[复制链接]

2

主题

0

回帖

7

积分

新手上路

积分
7
发表于 2024-9-13 11:46:33 | 显示全部楼层 |阅读模式
目录前言1.基本知识2.Demo2.1Demo1(同步)2.2Demo2(错误)2.3Demo3(不正确的异步)2.4Demo4(正确异步)3.完整版4.拓展4.1asyncio.create_task(coroutine)4.2asyncio.gather(*coroutines_or_futures,return_exceptions=False)4.3字符串拼接前言对于异步的基本知识推荐阅读我之前的文章:详细讲解Python中的aioschedule定时任务操作java关于@Async异步调用详细解析附代码【操作系统】线程与进程的深入剖析(全)【操作系统】守护线程和守护进程的区别1.基本知识在Python中,async和await是用于异步编程的关键字,引入了异步/协程(coroutine)的概念异步编程是一种处理并发任务的方式,使得程序能够在等待某些I/O操作(如文件读写、网络请求等)的同时继续执行其他任务,而不会发生阻塞异步(Asynchronous):在异步编程中,程序不会等待某些I/O操作完成,而是继续执行其他任务,待操作完成后再回来处理结果协程(Coroutine):协程是一种轻量级的线程,可以在执行过程中暂停并让出控制权,然后在需要时恢复执行使用协程可以更有效地利用系统资源,避免线程切换的开销作用:提高程序效率:异步编程可以充分利用I/O等待时间,使得程序在等待操作完成时能够继续执行其他任务,从而提高了整体程序的效率。改善用户体验:在网络编程中,异步操作可以避免阻塞用户界面,使得应用程序更加流畅。简化并发编程:通过使用async和await关键字,可以更方便地编写并发程序,避免了传统多线程编程中的锁和同步问题。2.Demo以下例子会一步步体现异步的重要性!2.1Demo1(同步)为了比较异步,先给出同步的例子:fromtimeimportsleepdefgreet(name):print("Hello,"+name)sleep(2)#模拟一个耗时的操作print("Goodbye,"+name)#运行主函数if__name__=="__main__":greet("码农")greet("研究僧")123456789101112执行的顺序如下:(这就是同步,需要等待上一个操作执行完)2.2Demo2(错误)为了引入异步,我们先使用这个代码进行演示:(以下为错误代码)fromtimeimportsleepasyncdefgreet(name):print("Hello,"+name)sleep(2)#模拟一个耗时的操作print("Goodbye,"+name)#运行主函数if__name__=="__main__":greet("码农")greet("研究僧")1234567891011输出结果如下:F:\python_project\test\main.py:19:RuntimeWarning:coroutine'greet'wasneverawaitedgreet("码农")RuntimeWarning:EnabletracemalloctogettheobjectallocationtracebackF:\python_project\test\main.py:20:RuntimeWarning:coroutine'greet'wasneverawaitedgreet("研究僧")RuntimeWarning:Enabletracemalloctogettheobjectallocationtraceback123456截图如下:通过实战完善知识点:在Python中,async和await是一对配合使用的关键字,用于定义异步函数和在异步函数中等待其他异步操作完成配合使用可以实现协程的特性,使得异步编程更加简洁和易于理解async关键字:async用于定义一个异步函数,表明该函数是一个协程,可以在其中使用await关键字等待其他异步操作完成异步函数的执行不会阻塞事件循环,而是会立即返回一个协程对象。await关键字:await用于在异步函数内部等待其他协程执行完成,后面通常跟着一个需要等待的协程对象当遇到await关键字时,事件循环会挂起当前的协程,并执行其他任务,直到等待的协程完成后才会恢复执行当前协程这两个关键字配合使用的好处在于:简化异步编程:使用async和await关键字可以使异步编程更加直观和易于理解,避免了回调函数和复杂的异步调度逻辑。实现协程:async和await的组合使得函数可以在执行过程中暂停并恢复,实现了协程的特性,可以更灵活地处理异步任务。提高可读性:使用async和await可以使异步代码更加清晰和可读,使得程序逻辑更易于理解和维护。2.3Demo3(不正确的异步)修正为如下:(正确)importasynciofromtimeimportsleep#定义一个异步函数asyncdefgreet(name):print("Hello,"+name)sleep(2)#模拟一个耗时的操作print("Goodbye,"+name)asyncdefmain():awaitgreet("码农")awaitgreet("研究僧")#运行主函数if__name__=="__main__":asyncio.run(main())1234567891011121314151617或者importasyncio#定义一个异步函数asyncdefgreet(name):print("Hello,"+name)awaitasyncio.sleep(2)#模拟一个耗时的操作print("Goodbye,"+name)asyncdefmain():awaitgreet("码农")awaitgreet("研究僧")#运行主函数if__name__=="__main__":asyncio.run(main())123456789101112131415这两者的输出都为如下:光看上面的代码也只是同步输出,而不是异步输出的结果2.4Demo4(正确异步)为了体现异步执行的效果,可以使用asyncio.create_task()创建任务并发执行importasyncio#定义一个异步函数asyncdefgreet(name):print("Hello,"+name)awaitasyncio.sleep(2)#使用异步的sleep函数print("Goodbye,"+name)#执行异步函数asyncdefmain():#创建任务并发执行task1=asyncio.create_task(greet("码农"))task2=asyncio.create_task(greet("研究僧"))#等待所有任务完成awaitasyncio.gather(task1,task2)#运行主函数if__name__=="__main__":asyncio.run(main())1234567891011121314151617181920截图如下:3.完整版完整版代码如下:importasynciofromdatetimeimportdatetime#定义一个异步函数asyncdefgreet(name):print("Hello,"+name+str(datetime.now()))awaitasyncio.sleep(2)#使用异步的sleep函数print("Goodbye,"+name+str(datetime.now()))#执行异步函数asyncdefmain():#创建任务并发执行task1=asyncio.create_task(greet("码农"))task2=asyncio.create_task(greet("研究僧"))#等待所有任务完成awaitasyncio.gather(task1,task2)if__name__=="__main__":start=datetime.now()#记录程序开始执行的时间asyncio.run(main())#运行主函数end=datetime.now()#记录程序结束执行的时间print('elapsedtime=',end-start)#输出执行时间1234567891011121314151617181920212223输出结果如下:4.拓展对于上述代码,有个别函数拓展如下asyncio.create_task()和asyncio.gather()是Python中asyncio模块中的两个重要函数,用于创建和管理协程任务。都用于在异步编程中管理多个协程的执行,但是有着不同的作用和用法。总的来说,asyncio.create_task()用于并发执行多个协程任务,而asyncio.gather()用于等待多个协程任务的全部完成,并且可以收集执行结果这两个函数是asyncio中协程任务管理的重要工具4.1asyncio.create_task(coroutine)asyncio.create_task()用于创建一个协程任务,并安排其立即执行接受一个协程对象作为参数,并返回一个任务对象该任务对象可以用来控制和管理该协程的执行,包括取消、等待其执行完成等importasyncioasyncdefmy_coroutine():awaitasyncio.sleep(1)print("Coroutineexecuted")asyncdefmain():task=asyncio.create_task(my_coroutine())awaittask#等待任务执行完成asyncio.run(main())1234567891011以上使用asyncio.create_task()可以方便地并发执行多个协程4.2asyncio.gather(*coroutines_or_futures,return_exceptions=False)asyncio.gather()用于同时运行多个协程,并等待全部完成接受一系列的协程对象(或者Future对象)作为参数,并返回一个协程对象,该协程对象会在所有给定的协程都执行完毕后完成importasyncioasyncdefcoro1():awaitasyncio.sleep(1)return"Coroutine1"asyncdefcoro2():awaitasyncio.sleep(2)return"Coroutine2"asyncdefmain():result=awaitasyncio.gather(coro1(),coro2())print(result)asyncio.run(main())1234567891011121314154.3字符串拼接对于输出函数来说,一般都由字符串组成如果使用其他非字符串则需要进行转化datetime.now()返回的是一个datetime对象,不能直接与字符串拼接需要将datetime对象转换为字符串类型才能进行拼接使用str()函数将datetime对象转换为字符串print("Hello,"+name+",时间:"+str(datetime.now()))1或者使用字符串的format()方法进行格式化输出print("Hello,{},时间:{}".format(name,datetime.now()))1或者使用f-string格式化字符串print(f"Hello,{name},时间:{datetime.now()}")1这些都是将datetime.now()的结果转换为字符串后再与其他字符串进行拼接的方法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 11:09 , Processed in 0.719999 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表