一文吃透Python async/await!零基础入门+实战案例+流程图解🔥

在Python开发中,异步编程是提升程序IO效率的核心技能,而 async/await 是Python3.5+ 推出的原生异步语法糖✨,彻底简化了传统协程的复杂写法。

很多小伙伴分不清同步、异步、协程的区别,写不懂async/await的执行逻辑。今天这篇文章,从零到实战带你彻底搞懂,看完直接上手写异步代码!

一、先搞懂:为什么要用 async/await?🤔

1.1 同步代码的痛点

普通同步代码是串行执行的:上一行代码阻塞等待完成,才会执行下一行。遇到IO操作(网络请求、文件读写、数据库查询)时,CPU会闲置等待,极大浪费性能。

举个例子:批量请求10个网页,同步方式需要逐个等待,总耗时是所有请求耗时之和。

1.2 异步代码的优势

异步协程的核心:遇到IO阻塞不等待,切换去执行其他任务🚀,最大化利用CPU时间,大幅提升IO密集型程序的运行效率。

async/await 就是Python官方推荐的、最简洁的异步协程写法,替代了老旧的 yieldasyncio.coroutine 语法。

二、核心概念:3个关键词彻底理解💡

想要用好异步,先记住3个核心定义,简单易懂,无晦涩术语!

2.1 async:定义协程函数

在普通函数前加 async 关键字,这个函数就变成了协程函数

特性:调用协程函数,不会立即执行函数内部代码,只会返回一个协程对象,需要放入事件循环才能执行。

# 定义协程函数
async def demo():
    print("这是一个协程函数")

# 调用函数,返回协程对象,不执行内部代码
print(demo())  # 输出:<coroutine object demo at 0x...>

2.2 await:阻塞等待+任务切换

await 是异步代码的核心开关,只能写在 async 函数内部

作用:等待IO操作完成,在等待期间让出CPU,执行其他就绪任务

可等待对象:协程对象、Task任务、Future对象(日常开发只需关注前两者)。

简单总结:遇到await就暂停,IO等待时切任务,等待结束再恢复

2.3 事件循环(Event Loop)

事件循环是异步程序的调度中心🎯,相当于任务管家:

  • 接收所有协程任务

  • 监听任务状态(阻塞/就绪)

  • 自动切换、调度任务执行

所有async/await代码,必须依托事件循环才能运行。Python3.7+ 提供了极简入口:asyncio.run(),自动创建、关闭事件循环。

三、异步执行流程图解📊

用一张流程图看懂async/await完整执行逻辑,告别逻辑混乱!

渲染错误: Mermaid 渲染失败: Parse error on line 15: ... 所有任务结束,关闭循环 ```## 四、基础实战案例:入门必看✅ ----------------------^ Expecting '()', 'SOLID_OPEN_ARROW', 'DOTTED_OPEN_ARROW', 'SOLID_ARROW', 'SOLID_ARROW_TOP', 'SOLID_ARROW_BOTTOM', 'STICK_ARROW_TOP', 'STICK_ARROW_BOTTOM', 'SOLID_ARROW_TOP_DOTTED', 'SOLID_ARROW_BOTTOM_DOTTED', 'STICK_ARROW_TOP_DOTTED', 'STICK_ARROW_BOTTOM_DOTTED', 'SOLID_ARROW_TOP_REVERSE', 'SOLID_ARROW_BOTTOM_REVERSE', 'STICK_ARROW_TOP_REVERSE', 'STICK_ARROW_BOTTOM_REVERSE', 'SOLID_ARROW_TOP_REVERSE_DOTTED', 'SOLID_ARROW_BOTTOM_REVERSE_DOTTED', 'STICK_ARROW_TOP_REVERSE_DOTTED', 'STICK_ARROW_BOTTOM_REVERSE_DOTTED', 'BIDIRECTIONAL_SOLID_ARROW', 'DOTTED_ARROW', 'BIDIRECTIONAL_DOTTED_ARROW', 'SOLID_CROSS', 'DOTTED_CROSS', 'SOLID_POINT', 'DOTTED_POINT', got 'NEWLINE'

3个任务,每个等待2秒,总耗时6秒,完全串行阻塞。

4.2 异步基础代码(初步提速)

注意:异步等待必须用 asyncio.sleep(),不能用普通 time.sleep()(普通睡眠会阻塞整个循环)

import asyncio
import time

# 定义异步任务
async def task(name):
    print(f"任务{name} 开始执行")
    await asyncio.sleep(2)  # 异步IO等待,不阻塞,让出CPU
    print(f"任务{name} 执行完成")

async def main():
    # 逐个执行协程(注意:这不是并发!)
    await task("A")
    await task("B")
    await task("C")

if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())  # 启动事件循环
    end = time.time()
    print(f"总耗时:{end - start:.2f}s")

# 输出结果
# 任务A 开始执行
# 任务A 执行完成
# 任务B 开始执行
# 任务B 执行完成
# 任务C 开始执行
# 任务C 执行完成
# 总耗时:6.00s

这里总耗时还是6秒!重点避坑:单纯await串行调用,只是异步函数写法,没有实现并发

4.3 真正的异步并发(核心用法🔥)

想要实现多任务并发,必须将协程封装为Task任务,交给事件循环统一调度,使用asyncio.gather() 批量执行!

import asyncio
import time

async def task(name):
    print(f"任务{name} 开始执行")
    await asyncio.sleep(2)  # 异步阻塞,切换其他任务
    print(f"任务{name} 执行完成")

async def main():
    # 创建多个并发任务
    tasks = [task("A"), task("B"), task("C")]
    # 批量执行所有任务,实现并发
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(f"总耗时:{end - start:.2f}s")

# 输出结果
# 任务A 开始执行
# 任务B 开始执行
# 任务C 开始执行
# 任务A 执行完成
# 任务B 执行完成
# 任务C 执行完成
# 总耗时:2.00s

✅ 质变!3个任务并发执行,总耗时仅2秒,效率提升3倍!这就是异步的核心魅力。

五、进阶实战:异步网络请求(爬虫必备)🌐

日常开发最常用的场景:异步批量网络请求,替代同步requests,大幅提升爬虫、接口请求效率。

异步请求需要使用 aiohttp 库(需提前安装:pip install aiohttp

import asyncio
import aiohttp
import time

# 异步请求函数
async def fetch_url(session, url):
    print(f"正在请求:{url}")
    async with session.get(url) as response:
        text = await response.text()
        print(f"请求完成:{url},响应长度:{len(text)}")
        return len(text)

async def main():
    # 批量请求地址
    urls = [
        "https://www.baidu.com",
        "https://www.qq.com",
        "https://www.csdn.net"
    ]
    # 创建异步会话
    async with aiohttp.ClientSession() as session:
        # 封装任务
        tasks = [fetch_url(session, url) for url in urls]
        # 并发执行
        await asyncio.gather(*tasks)

if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(f"异步请求总耗时:{end - start:.2f}s")

运行结果:多个网址同时发起请求,无需逐个等待,极大缩短批量请求耗时。

六、核心避坑指南⚠️(新手必看)

很多人写不好异步代码,都是踩了这几个坑!

6.1 禁止在async函数中使用同步阻塞方法

不要在异步函数中用 time.sleep()、同步请求、文件读写等同步操作,会阻塞整个事件循环!

✅ 正确:异步场景用 asyncio.sleep()aiohttp、异步文件操作

6.2 await 不能单独使用

await 必须嵌套在 async def 函数内,普通函数、全局作用域直接报语法错误。

6.4 协程必须交给事件循环执行

直接调用协程函数(如 task())不会执行代码,必须通过 asyncio.run()gather 提交给事件循环。

6.5 异步只适合IO密集型场景

  • ✅ 适合:网络请求、文件读写、数据库操作、等待延时(IO密集型)

  • ❌ 不适合:数值计算、数据处理(CPU密集型),此时异步无提升,推荐多进程

七、核心知识点总结📝

关键字 作用 使用场景
async 定义协程函数 声明所有异步函数
await 等待IO、切换任务
async函数内部,修饰可等待对象
asyncio.gather 批量并发执行任务 多任务异步并发核心
asyncio.run 启动事件循环 Python3.7+ 程序入口

八、写在最后✨

async/await 是Python异步编程的基石,掌握它可以轻松实现高并发IO程序,在爬虫、接口开发、后端服务、定时任务等场景中大幅优化性能。

核心精髓就一句话:async定义异步函数,await卡点切任务,gather实现多并发

更多推荐