东莞连衣裙 东莞网站建设南充免费推广网站
2026/1/15 23:39:55 网站建设 项目流程
东莞连衣裙 东莞网站建设,南充免费推广网站,石家庄微网站建设,Tp5即做网站又提供api接口Python async 和 await 详细解析 async 和 await 是 Python 3.5 及以上版本引入的异步编程核心语法#xff0c;用于实现「非阻塞式」代码执行#xff0c;解决传统同步编程中高IO等待#xff08;如网络请求、数据库操作、文件读写#xff09;导致的资源浪费问题#xff0c;…Pythonasync和await详细解析async和await是 Python 3.5 及以上版本引入的异步编程核心语法用于实现「非阻塞式」代码执行解决传统同步编程中高IO等待如网络请求、数据库操作、文件读写导致的资源浪费问题大幅提升程序在高IO场景下的并发性能。一、核心概念铺垫同步 vs 异步在理解async/await之前先明确同步编程和异步编程的核心差异1. 同步编程默认模式执行逻辑代码按顺序串行执行一个任务执行完成包括等待时间后下一个任务才会开始。典型问题遇到IO等待如请求接口、读取大文件时整个程序会「阻塞」在该任务上浪费CPU资源。示例同步请求3个接口每个接口耗时2秒其中1.9秒是网络等待总耗时约6秒CPU在等待期间处于闲置状态。2. 异步编程async/await实现执行逻辑代码按事件循环驱动的非阻塞模式执行当一个任务遇到IO等待时不会阻塞整个程序而是将控制权交还给事件循环去执行其他就绪任务待IO任务完成后再继续执行该任务的后续代码。核心优势在IO等待期间充分利用CPU资源提升程序并发处理能力。示例异步请求3个接口总耗时约2秒接近单个接口的耗时CPU在等待期间可处理其他任务。二、async定义异步函数/协程1. 核心定义async是一个关键字用于定义异步函数也称为「协程函数」Coroutine Function标志着该函数内部包含非阻塞执行的逻辑不能直接同步调用执行必须通过异步方式触发。2. 语法格式# 定义异步函数协程函数asyncdef异步函数名(参数列表):# 函数体可包含 await 语句也可不含执行逻辑return返回值3. 关键特性异步函数被调用时不会立即执行函数体而是返回一个「协程对象Coroutine Object」这是异步函数与普通同步函数的核心区别。异步函数的返回值不能通过普通赋值获取必须通过await或异步框架的相关方法获取。4. 示例定义异步函数# 定义一个简单的异步函数asyncdefasync_hello():print(进入异步函数)# 模拟IO等待后续会用 asyncio.sleep 替代这里先演示结构awaitasyncio.sleep(1)print(异步函数执行完成)return异步函数返回结果# 直接调用异步函数不会执行函数体仅返回协程对象coroasync_hello()print(调用异步函数返回的结果,coro)# 输出调用异步函数返回的结果 coroutine object async_hello at 0x10xxxxx5. 协程的本质协程Coroutine是「轻量级线程」由Python程序自身控制而非操作系统内核控制切换开销远小于传统线程。异步函数就是协程的载体async关键字的核心作用是标记该函数为协程函数使其能被事件循环调度执行。三、await挂起协程等待异步任务完成1. 核心定义await是一个关键字只能在异步函数async def定义的函数内部使用用于「挂起当前协程的执行」等待一个「可等待对象Awaitable」执行完成并返回结果在此期间将控制权交还给事件循环允许其他协程执行。2. 核心作用等待异步任务完成阻塞当前协程而非整个程序直到被等待的对象执行完毕。非阻塞式等待在等待期间事件循环可以调度其他就绪的协程执行充分利用CPU资源。获取异步任务返回值await会接收被等待对象的返回值可直接赋值给变量使用。3. 可等待对象Awaitableawait后面只能跟「可等待对象」否则会抛出TypeError常见的可等待对象有3类协程对象Coroutineasync def函数调用后返回的对象最常用。任务对象Task由asyncio.create_task()或loop.create_task()创建的对象用于封装协程支持并发执行多个协程。未来对象Future表示一个尚未完成的异步操作结果通常用于底层异步编程如异步IO框架实现。4. 语法格式asyncdef异步函数名():# 等待可等待对象执行完成并获取返回值结果await可等待对象 后续执行逻辑5. 示例await等待协程执行importasyncio# 定义异步函数模拟IO任务asyncdefsimulate_io_task(task_name,delay):print(f开始执行异步任务{task_name}等待{delay}秒)# await 等待 asyncio.sleep异步睡眠非阻塞awaitasyncio.sleep(delay)# asyncio.sleep 是异步函数返回协程对象print(f异步任务{task_name}执行完成)returnf{task_name}返回结果# 定义主异步函数asyncdefmain():print( 开始执行主异步函数 )# 依次等待3个异步任务执行串行异步总耗时约 1236 秒result1awaitsimulate_io_task(任务1,1)result2awaitsimulate_io_task(任务2,2)result3awaitsimulate_io_task(任务3,3)# 打印返回结果print(\n 所有任务执行完成 )print(结果1,result1)print(结果2,result2)print(结果3,result3)# 启动事件循环执行主协程if__name____main__:asyncio.run(main())6. 关键注意点await不能在同步函数中使用如果在普通def定义的同步函数中使用await会直接抛出语法错误。await会挂起当前协程而非整个程序只有当前协程被阻塞事件循环可以正常调度其他协程。多个await串行执行时仍会按顺序等待如上述示例3个任务串行执行总耗时等于各任务耗时之和若要实现并发需使用asyncio.create_task()封装任务。四、异步编程的核心事件循环Event Loopasync和await本身无法直接运行异步代码必须依赖「事件循环」Event Loop—— 它是Python异步编程的「核心调度器」负责管理所有协程的执行顺序、分发IO事件、切换协程等。1. 事件循环的核心职责注册和调度协程/任务。监控协程的执行状态当协程被await挂起时切换到其他就绪协程。当被挂起的协程完成IO等待后将其重新加入就绪队列等待继续执行。终止整个异步程序的执行所有任务完成后。2. 常用事件循环操作在Python 3.7及以上版本推荐使用asyncio.run()来启动事件循环它会自动创建、运行和关闭事件循环简化异步代码的启动流程。示例并发执行多个异步任务使用asyncio.create_task()importasyncioasyncdefsimulate_io_task(task_name,delay):print(f开始执行异步任务{task_name}等待{delay}秒)awaitasyncio.sleep(delay)print(f异步任务{task_name}执行完成)returnf{task_name}返回结果asyncdefmain():print( 开始执行主异步函数并发模式 )# 1. 创建任务对象将协程封装为Task加入事件循环就绪队列task1asyncio.create_task(simulate_io_task(任务1,1))task2asyncio.create_task(simulate_io_task(任务2,2))task3asyncio.create_task(simulate_io_task(任务3,3))# 2. 并发等待所有任务完成总耗时约 3 秒等于最长任务的耗时result1awaittask1 result2awaittask2 result3awaittask3# 3. 打印返回结果print(\n 所有任务执行完成 )print(结果1,result1)print(结果2,result2)print(结果3,result3)if__name____main__:# asyncio.run() 自动创建事件循环运行主协程执行完毕后关闭事件循环asyncio.run(main())执行结果分析 开始执行主异步函数并发模式 开始执行异步任务任务1等待 1 秒 开始执行异步任务任务2等待 2 秒 开始执行异步任务任务3等待 3 秒 异步任务任务1 执行完成 异步任务任务2 执行完成 异步任务任务3 执行完成 所有任务执行完成 结果1 任务1 返回结果 结果2 任务2 返回结果 结果3 任务3 返回结果3个任务几乎同时启动总耗时约3秒等于耗时最长的任务3实现了真正的并发异步执行。这就是async/await的核心价值在IO密集型场景下通过非阻塞等待大幅提升并发效率。五、async/await的使用场景与限制1. 最佳使用场景IO密集型任务async/await对IO密集型任务有显著性能提升常见场景包括网络请求接口调用、爬虫、微服务通信推荐使用aiohttp替代requests。数据库操作异步数据库查询推荐使用asyncmy替代pymysql、asyncpg替代psycopg2。文件读写大文件异步读写推荐使用aiofiles替代内置open。消息队列异步消费/生产消息。2. 不适用场景CPU密集型任务async/await对CPU密集型任务如大数据计算、加密解密、图形渲染几乎没有性能提升甚至可能因为协程切换开销导致性能下降。原因CPU密集型任务会持续占用CPU资源不会产生IO等待事件循环无法切换协程无法发挥异步编程的优势。替代方案对于CPU密集型任务推荐使用multiprocessing多进程或concurrent.futures.ProcessPoolExecutor。3. 关键使用限制await只能在async def函数内部使用不能在同步函数def或全局作用域中使用。异步函数不能直接同步调用必须通过asyncio.run()、await或asyncio.create_task()触发执行。异步代码必须使用异步库同步库如requests、pymysql会阻塞事件循环导致异步编程失效必须使用对应的异步库如aiohttp、asyncmy。协程切换是「协作式」的而非「抢占式」的只有当协程遇到await挂起时才会将控制权交还给事件循环若一个协程长时间不挂起会阻塞其他协程的执行。六、async/await与同步代码的对比示例1. 同步代码requests调用接口importrequestsimporttimedefsync_request(url,delay):print(f开始同步请求{url})# 同步请求阻塞等待responserequests.get(url)time.sleep(delay)# 模拟额外等待print(f同步请求{url}完成状态码{response.status_code})returnresponse.status_codedefmain():start_timetime.perf_counter()# 串行执行3个同步请求sync_request(https://httpbin.org/get,1)sync_request(https://httpbin.org/get,1)sync_request(https://httpbin.org/get,1)end_timetime.perf_counter()print(f\n总耗时{end_time-start_time:.2f}秒)if__name____main__:main()执行结果总耗时约 6~9 秒包含网络请求时间3秒睡眠时间全程串行阻塞。2. 异步代码aiohttp调用接口importaiohttpimportasyncioimporttimeasyncdefasync_request(url,delay):print(f开始异步请求{url})# 异步请求非阻塞等待asyncwithaiohttp.ClientSession()assession:asyncwithsession.get(url)asresponse:awaitasyncio.sleep(delay)# 异步睡眠非阻塞print(f异步请求{url}完成状态码{response.status})returnresponse.statusasyncdefmain():start_timetime.perf_counter()# 并发执行3个异步请求task1asyncio.create_task(async_request(https://httpbin.org/get,1))task2asyncio.create_task(async_request(https://httpbin.org/get,1))task3asyncio.create_task(async_request(https://httpbin.org/get,1))awaittask1awaittask2awaittask3 end_timetime.perf_counter()print(f\n总耗时{end_time-start_time:.2f}秒)if__name____main__:asyncio.run(main())执行结果总耗时约 2~3 秒包含网络请求时间1秒睡眠时间全程并发非阻塞性能提升显著。七、总结async用于定义协程函数异步函数标记函数包含非阻塞逻辑调用后返回协程对象不立即执行。await仅在协程函数内部使用用于挂起当前协程等待可等待对象完成期间将控制权交还给事件循环实现非阻塞等待。核心价值在IO密集型场景下通过事件循环调度协程充分利用CPU资源大幅提升程序并发处理能力。运行依赖异步代码必须通过asyncio.run()启动事件循环且需配合异步库使用避免同步库阻塞事件循环。适用边界仅适用于IO密集型任务CPU密集型任务推荐使用多进程。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询