【Python 异步】第二篇:async 与 await 的深度互博——协程的“呼吸”艺术

📅 发布时间:2026/7/16 13:34:08 👁️ 浏览次数:
【Python 异步】第二篇:async 与 await 的深度互博——协程的“呼吸”艺术
专栏进度02 / 03 (异步 IO 专题)如果说同步代码是“一杆子插到底”那么异步代码就是有节奏的“呼吸”。async 定义了这段呼吸的频率而 await 则是那次深长的“呼气”。一、 async将函数标记为“协程”当你给一个函数加上 async 前缀时它就不再是一个普通的函数了。asyncdefsay_hello():returnHelloresultsay_hello()print(result)# coroutine object say_hello at 0x...专家视角调用 async 函数不会立即执行内部代码而是返回一个协程对象Coroutine Object。它就像一份“待办清单”此时还没有开始执行。二、 await逻辑的“挂起”与“让权”await 是异步编程中最具魔力的关键字。它的核心作用有两个等待结果 和 让出控制权。工作逻辑挂起Suspend当遇到 await 时当前的协程会立刻暂停并将自己状态局部变量、执行进度保存在内存中。让权Yield它会告诉事件循环“我现在要等 IO比如网络下载你先去处理别的任务吧。”唤醒Resume当 await 后面的 IO 操作完成后事件循环会重新跳回该协程恢复其上下文并继续运行。三、 深度实战Task 与 Future 的协同在实际开发中我们很少直接操作协程对象而是将其封装为 Task任务。importasyncioasyncdefdownload_file(name):print(f开始下载{name}...)awaitasyncio.sleep(2)# 模拟网络 IOprint(f{name}下载完成)returnf{name}_dataasyncdefmain():# 创建任务Task 会被立即加入事件循环等待执行task1asyncio.create_task(download_file(文件1))task2asyncio.create_task(download_file(文件2))# 在这里task1 和 task2 实际上已经在并行运行了print(主程序继续执行其他逻辑...)# 最终拿到结果res1awaittask1 res2awaittask2print(f全部完成{res1},{res2})asyncio.run(main())底层机制Future它是结果的“占位符”。await 一个 Future 意味着“等它有结果了我再动”。Task是 Future 的子类。它负责把协程对象包装起来丢进事件循环。四、 避坑指南await 的位置决定了并发性这是很多新手最容易犯的低级错误反面教材变回同步Python这样写下载 2 永远在下载 1 完成后才开始完全没有并发res1awaitdownload_file(文件1)res2awaitdownload_file(文件2)专家写法真正并发使用 asyncio.gather() 或 asyncio.create_task()。五、 核心揭秘协程是怎么找回“记忆”的底层真相Python 的协程底层是基于**生成器Generator**的。每一个协程在挂起时Python 解释器都会保留该协程的 Frame Object栈帧对象。这个对象里存着所有的局部变量和指令指针。这就是为什么它能像“暂停键”一样在两秒后再精准地从断点处苏醒。