Python 异步编程完全指南(一):初识异步编程
·
Python 异步编程完全指南(一):初识异步编程

前言:为什么你必须掌握异步编程?
想象一下这个场景:你需要从 100 个网站抓取数据。
- 传统同步方式:一个接一个地请求,每个请求等待 1 秒,总共需要 100 秒
- 异步方式:同时发起 100 个请求,总共只需要 约 1 秒
效率提升 100 倍! 这就是异步编程的魔力。
在当今互联网时代,高并发、高性能已经成为应用的标配需求。无论你是:
- 🕷️ 开发爬虫系统
- 🌐 构建 Web 服务
- 📊 处理实时数据流
- 🤖 开发聊天机器人
异步编程都是你绑不开的必修课。
本系列将带你从零开始,彻底掌握 Python 异步编程的精髓。
一、理解异步:从生活场景说起
1.1 餐厅点餐的启示
假设你去餐厅吃饭:
同步模式(糟糕的餐厅):
服务员 → 接待客人A → 等待A点完餐 → 送餐给A → 等A吃完 → 接待客人B → ...
一个服务员一次只能服务一位客人,效率极低。
异步模式(高效的餐厅):
服务员 → 接待客人A → A看菜单时去接待B → B看菜单时去送餐给C → ...
服务员在等待时去做其他事情,效率大幅提升。
1.2 程序世界中的同步与异步
┌─────────────────────────────────────────────────────────────────┐
│ 同步执行模型 │
├─────────────────────────────────────────────────────────────────┤
│ 任务A ████████████ │
│ 任务B ████████████ │
│ 任务C ████████████ │
│ ─────────────────────────────────────────────────────► 时间 │
│ 总耗时: 任务A + 任务B + 任务C = 30秒 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 异步执行模型 │
├─────────────────────────────────────────────────────────────────┤
│ 任务A ████████████ │
│ 任务B ████████████ │
│ 任务C ████████████ │
│ ─────────────────────────────────────────────────────► 时间 │
│ 总耗时: max(任务A, 任务B, 任务C) = 10秒 │
└─────────────────────────────────────────────────────────────────┘
1.3 关键概念辨析
| 概念 | 含义 | 类比 |
|---|---|---|
| 同步 (Sync) | 按顺序执行,等待完成 | 排队买票,必须等前面的人买完 |
| 异步 (Async) | 不等待,继续做其他事 | 取号等候,可以先去逛街 |
| 并发 (Concurrent) | 同一时间段处理多个任务 | 一个厨师同时炒几个菜 |
| 并行 (Parallel) | 同一时刻执行多个任务 | 多个厨师同时炒菜 |
| 阻塞 (Blocking) | 等待操作完成才能继续 | 打电话时必须等对方接听 |
| 非阻塞 (Non-blocking) | 不等待,立即返回 | 发微信后不用等回复 |
💡 重要理解:Python 的 asyncio 实现的是单线程并发,通过事件循环在多个任务间切换,而不是真正的并行执行。
二、Python 异步编程基础
2.1 第一个异步程序
让我们从最简单的例子开始:
import asyncio
# 定义一个协程函数(使用 async 关键字)
async def say_hello():
print("Hello")
await asyncio.sleep(1) # 异步等待 1 秒
print("World")
# 运行协程
asyncio.run(say_hello())
输出:
Hello
(等待 1 秒)
World
代码解析:
async def- 定义一个协程函数await- 暂停当前协程,等待异步操作完成asyncio.run()- 运行协程的入口点
2.2 理解 async/await 语法
async def - 定义协程函数
# 普通函数
def regular_function():
return "I'm regular"
# 协程函数(加上 async 关键字)
async def coroutine_function():
return "I'm a coroutine"
# 调用对比
print(regular_function()) # 输出: I'm regular
print(coroutine_function()) # 输出: <coroutine object ...> ← 返回协程对象!
⚠️ 注意:调用协程函数不会立即执行,而是返回一个协程对象,需要用
await或asyncio.run()来执行。
await - 等待协程完成
async def fetch_data():
print("开始获取数据...")
await asyncio.sleep(2) # 模拟网络请求
print("数据获取完成!")
return {"status": "success"}
async def main():
# await 会暂停当前协程,等待 fetch_data() 完成
result = await fetch_data()
print(f"结果: {result}")
asyncio.run(main())
2.3 同步 vs 异步:代码对比
场景:模拟 3 个耗时 1 秒的网络请求
同步版本
import time
def fetch_data(id):
print(f"开始请求 {id}")
time.sleep(1) # 模拟耗时操作
print(f"完成请求 {id}")
return f"data_{id}"
def main():
start = time.time()
result1 = fetch_data(1) # 等待 1 秒
result2 = fetch_data(2) # 再等待 1 秒
result3 = fetch_data(3) # 再等待 1 秒
print(f"结果: {result1}, {result2}, {result3}")
print(f"总耗时: {time.time() - start:.2f} 秒")
main()
输出:
开始请求 1
完成请求 1
开始请求 2
完成请求 2
开始请求 3
完成请求 3
结果: data_1, data_2, data_3
总耗时: 3.01 秒
异步版本
import asyncio
import time
async def fetch_data(id):
print(f"开始请求 {id}")
await asyncio.sleep(1) # 异步等待
print(f"完成请求 {id}")
return f"data_{id}"
async def main():
start = time.time()
# 使用 gather 并发执行多个协程
results = await asyncio.gather(
fetch_data(1),
fetch_data(2),
fetch_data(3)
)
print(f"结果: {results}")
print(f"总耗时: {time.time() - start:.2f} 秒")
asyncio.run(main())
输出:
开始请求 1
开始请求 2
开始请求 3
完成请求 1
完成请求 2
完成请求 3
结果: ['data_1', 'data_2', 'data_3']
总耗时: 1.00 秒
2.4 对比总结
| 指标 | 同步版本 | 异步版本 | 提升 |
|---|---|---|---|
| 总耗时 | 3.01 秒 | 1.00 秒 | 3 倍 |
| 代码复杂度 | 简单 | 稍复杂 | - |
| 资源利用率 | 低 | 高 | - |
三、动手练习
练习 1:Hello Async
编写一个异步函数,打印 “开始”,等待 2 秒,然后打印 “结束”。
import asyncio
async def hello_async():
# 你的代码
pass
asyncio.run(hello_async())
点击查看答案
import asyncio
async def hello_async():
print("开始")
await asyncio.sleep(2)
print("结束")
asyncio.run(hello_async())
练习 2:并发倒计时
编写一个程序,同时启动 3 个倒计时器(分别从 3、2、1 开始),观察输出顺序。
import asyncio
async def countdown(name, n):
# 你的代码
pass
async def main():
# 你的代码
pass
asyncio.run(main())
点击查看答案
import asyncio
async def countdown(name, n):
while n > 0:
print(f"{name}: {n}")
await asyncio.sleep(1)
n -= 1
print(f"{name}: 完成!")
async def main():
await asyncio.gather(
countdown("A", 3),
countdown("B", 2),
countdown("C", 1)
)
asyncio.run(main())
输出:
A: 3
B: 2
C: 1
A: 2
B: 1
C: 完成!
A: 1
B: 完成!
A: 完成!
四、本篇小结
本篇我们学习了:
- ✅ 异步编程的意义:大幅提升 I/O 密集型任务的效率
- ✅ 核心概念辨析:同步/异步、并发/并行、阻塞/非阻塞
- ✅ 基本语法:
async def定义协程,await等待执行 - ✅ 运行方式:
asyncio.run()启动异步程序 - ✅ 并发执行:
asyncio.gather()同时运行多个协程
下篇预告
在下一篇 核心概念篇 中,我们将深入学习:
- 事件循环 (Event Loop) 的工作原理
- Task 对象的创建和管理
- gather、wait、TaskGroup 的区别和使用场景
- 协程的生命周期
如果这篇文章对你有帮助,欢迎点赞、收藏、关注!有问题欢迎评论区讨论。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)