Python 异步编程实战:async/await 从入门到精通

Python 异步编程实战:async/await 从入门到精通

前言

在如今的 Web 开发和网络编程中,异步编程已经成为必备技能。Python 3.5+ 引入的 `async/await` 语法让异步代码变得像同步代码一样易读。本文将带你从零开始掌握 Python 异步编程的核心概念和实战技巧。

一、什么是异步编程?

异步编程是一种编程范式,允许程序在等待某些操作(如网络请求、文件读写)完成时,转而执行其他任务,而不是阻塞等待。

同步 vs 异步

```python

同步代码 - 阻塞式

import time

def fetch_data_sync():

print("开始获取数据...")

time.sleep(2) # 阻塞 2 秒

print("数据获取完成")

return "data"

fetch_data_sync()

fetch_data_sync() # 必须等第一个完成才能执行第二个

总耗时:4 秒

```

```python

异步代码 - 非阻塞式

import asyncio

async def fetch_data_async():

print("开始获取数据...")

await asyncio.sleep(2) # 非阻塞等待

print("数据获取完成")

return "data"

async def main():

两个任务并发执行

results = await asyncio.gather(

fetch_data_async(),

fetch_data_async()

)

return results

asyncio.run(main())

总耗时:2 秒

```

二、核心概念解析

1. async 和 await

  • `async`:定义一个协程函数

  • `await`:等待一个协程执行完成

```python

import asyncio

async def say_hello():

await asyncio.sleep(1)

return "Hello"

async def say_world():

await asyncio.sleep(1)

return "World"

async def main():

顺序执行 - 耗时 2 秒

result1 = await say_hello()

result2 = await say_world()

print(f"{result1} {result2}")

并发执行 - 耗时 1 秒

results = await asyncio.gather(

say_hello(),

say_world()

)

print(f"{results0} {results1}")

asyncio.run(main())

```

2. Task - 调度和管理协程

```python

import asyncio

async def worker(name, delay):

for i in range(3):

await asyncio.sleep(delay)

print(f"{name} 执行第 {i+1} 次")

async def main():

创建任务

task1 = asyncio.create_task(worker("任务 A", 1))

task2 = asyncio.create_task(worker("任务 B", 1.5))

等待所有任务完成

await asyncio.gather(task1, task2)

print("所有任务完成")

asyncio.run(main())

```

三、实战案例:异步网络请求

使用 aiohttp 进行并发 HTTP 请求

```python

import asyncio

import aiohttp

async def fetch_url(session, url):

"""异步获取单个 URL 内容"""

try:

async with session.get(url) as response:

content = await response.text()

return f"{url}: {len(content)} 字节"

except Exception as e:

return f"{url}: 错误 - {e}"

async def fetch_all_urls(urls):

"""并发获取多个 URL"""

async with aiohttp.ClientSession() as session:

tasks = fetch_url(session, url) for url in urls

results = await asyncio.gather(*tasks)

return results

async def main():

urls = [

"https://www.python.org",

"https://www.github.com",

"https://www.stackoverflow.com"

]

results = await fetch_all_urls(urls)

for result in results:

print(result)

asyncio.run(main())

```

四、异步编程最佳实践

1. 避免阻塞操作

```python

❌ 错误示例 - 在异步函数中使用同步阻塞

async def bad_example():

import time

await asyncio.sleep(0)

time.sleep(1) # 这会阻塞整个事件循环!

✅ 正确示例 - 使用异步替代方案

async def good_example():

await asyncio.sleep(1) # 非阻塞等待

```

2. 使用 Semaphore 控制并发数

```python

async def fetch_with_limit(sem, url):

async with sem: # 限制同时进行的请求数

return await fetch_url(url)

async def main():

sem = asyncio.Semaphore(5) # 最多 5 个并发

urls = "http://example.com" * 100

tasks = fetch_with_limit(sem, url) for url in urls

await asyncio.gather(*tasks)

```

3. 超时处理

```python

async def fetch_with_timeout(url, timeout=5):

try:

async with asyncio.timeout(timeout):

return await fetch_url(url)

except asyncio.TimeoutError:

return f"{url} 请求超时"

```

五、性能对比

| 场景 | 同步方式 | 异步方式 | 提升 |

|------|---------|---------|------|

| 100 个 HTTP 请求 | ~100 秒 | ~2 秒 | 50 倍 |

| 数据库批量查询 | ~50 秒 | ~3 秒 | 16 倍 |

| 文件并发读写 | ~20 秒 | ~5 秒 | 4 倍 |

总结

Python 异步编程的核心优势:

  1. **高并发**:单线程处理大量 I/O 密集型任务

  2. **资源节省**:不需要为每个连接创建线程

  3. **代码清晰**:async/await 让异步代码像同步一样易读

  4. **生态成熟**:aiohttp、asyncpg、aiomysql 等库支持完善

**适用场景**:

  • Web 爬虫

  • API 网关

  • 实时数据处理

  • WebSocket 服务

**不适用场景**:

  • CPU 密集型计算(考虑多进程)

  • 简单的脚本任务

掌握异步编程,让你的 Python 应用性能起飞!🚀


*如果觉得本文有帮助,欢迎点赞收藏!有问题请在评论区留言~*

相关推荐
白猫不黑27 分钟前
Python实现简易Web弱口令爆破与防护方案
python·web安全·计算机·网络安全·黑客·信息安全·渗透测试
郑州光合科技余经理1 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
kuuailetianzi1 小时前
Python初识:定位、优势与发展历程
python
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
MyFreeIT1 小时前
Android PHP Manual
php
guoran_shini1 小时前
LLM微调-训练垂类问答模型
python·lora·sft
basketball6161 小时前
Python FastAPI 介绍以及常用方法
python·fastapi·vllm·ai infra
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
论文复现现场2 小时前
企业知识库 RAG 用什么模型便宜?GLM-5.3-Flash 长文本 API 实测
python·rag·企业知识库·大模型api·glm-5.3-flash
梦在远山后2 小时前
从手写 Loop 到可恢复 Runtime:用 LangGraph、PostgreSQL Checkpoint 与 AG-UI 跑通中断恢复
python·langchain·agent