本文由一缘原创整理,系统梳理 Python 协程与异步编程的原理、asyncio、实战技巧,适合所有 Python/后端开发者。

Python 协程与异步编程实战

协程是 Python 高性能并发的核心,asyncio 是官方异步编程标准库。


1. 什么是协程?

  • 协程是一种用户态的轻量级线程(微线程)
  • 通过 async def 定义,await 挂起等待

2. async/await 基本用法

import asyncio

async def hello():
    print('Hello ...')
    await asyncio.sleep(1)
    print('... World!')

asyncio.run(hello())

输出:

Hello ...
(1秒后)
... World!

3. asyncio 事件循环

  • 事件循环负责调度所有协程任务
  • asyncio.run() 自动创建和关闭事件循环

4. Task 与 Future

  • Task 是对协程的进一步封装,支持并发调度
  • Future 表示一个尚未完成的结果
import asyncio

async def foo():
    await asyncio.sleep(1)
    return 42

async def main():
    task = asyncio.create_task(foo())
    print('Task created')
    result = await task
    print('Result:', result)

asyncio.run(main())

输出:

Task created
(1秒后)
Result: 42

5. 并发 vs 并行

  • 并发:单线程下切换任务(协程)
  • 并行:多线程/多进程同时执行
import asyncio

async def work(n):
    print(f'start {n}')
    await asyncio.sleep(1)
    print(f'end {n}')

async def main():
    await asyncio.gather(work(1), work(2), work(3))

asyncio.run(main())

输出:

start 1
start 2
start 3
(1秒后)
end 1
end 2
end 3

6. 协程中的异常处理

import asyncio

async def error():
    raise ValueError('出错了')

async def main():
    try:
        await error()
    except Exception as e:
        print('捕获异常:', e)

asyncio.run(main())

输出:

捕获异常: 出错了

7. 实战:异步爬虫

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()

async def main():
    urls = ['https://httpbin.org/delay/1'] * 3
    results = await asyncio.gather(*(fetch(url) for url in urls))
    print([len(r) for r in results])

asyncio.run(main())

输出:

[...3个页面内容长度...]

8. 协程的最佳实践

  • 优先用 asyncio 官方库,避免滥用线程/进程
  • 用 gather 并发调度,合理处理异常
  • 避免阻塞操作(如 time.sleep、同步 I/O)
  • 善用 async with、async for

结语

协程和异步编程是 Python 高性能后端的核心,理解 asyncio 能让你写出高并发、可扩展的应用。欢迎留言交流更多 Python 深度问题!