编程学习网 > 编程语言 > Python > Python 异步编程入门:如何把同步函数变成异步函数?
2025
03-15

Python 异步编程入门:如何把同步函数变成异步函数?


写项目时,我们经常需要访问网络,比如调用 API、抓取网页数据等。很多时候,我们使用 requests 这样的库来发送 HTTP 请求。然而,requests 是一个同步库,这意味着每次请求都会阻塞整个程序,直到它完成才会继续运行。这就像你去餐厅点餐,必须等前面所有人点完、厨师做完他们的饭,你的食物才能上桌——效率感人至深。那么,有没有办法让 Python 同时处理多个请求,就像一个高效的餐厅一样,让多个请求同时进行,减少等待时间呢?

答案是异步编程(async programming)!

今天,我们就来学习如何把一个同步函数变成异步函数,让你的 Python 代码飞起来!

1. 为什么同步请求会“卡住”程序?
让我们先看看一个普通的同步请求是怎么工作的。

这里,requests.get(url) 是同步的,它会阻塞代码的执行,直到服务器返回数据。
假设你的程序要检查 100 个网站的状态,按照这种写法,每个请求都要等前一个完成才能继续,整个过程会非常慢。
如果我们能让这些请求同时进行,就能大大提高效率,这就是异步编程的作用!
2. 让同步函数“变身”异步函数
在 Python 中,我们可以使用 asyncio 来实现异步编程。但问题来了,requests.get() 是一个同步函数,不能直接在 async 里面用。
解决方案就是——用 asyncio.to_thread() 把它放到一个单独的线程中执行!
代码示例:异步获取多个网站状态


3. 代码解析
关键点:
1. async def fetch_status(url: str)• 这是一个异步函数(协程),用来获取网站的状态码。
2. await asyncio.to_thread(requests.get, url)• requests.get(url) 是同步函数,不能直接用 await。
• 解决方法:用 asyncio.to_thread() 把它放到单独的线程里执行,让它变成“伪异步”。
3. asyncio.create_task(fetch_status(url))• 这会立即创建一个任务,不会阻塞主程序。多个任务会同时运行。
4. await asyncio.gather(*tasks)• 这个函数会并行执行所有任务,并等待它们完成。
4. 为什么这样做更快?
如果你用 requests.get() 逐个请求 100 个网站,可能要等 100 秒(假设每个请求 1 秒)。
但用 asyncio.to_thread() 并行请求,就能同时发送多个请求,整体时间会缩短很多!
同步 vs. 异步:

异步的速度提升是显而易见的!
5. 什么时候应该用 asyncio.to_thread()?
适合的场景:
需要并行执行多个 I/O 操作(如网络请求、文件读写、数据库查询)。
你的代码依赖同步库(如 requests、openpyxl 等),但你又想让它异步执行。
不适合的场景:
CPU 密集型任务(如大规模计算、视频处理),因为 Python 的 GIL 限制了多线程的 CPU 性能。
代码本身已经是异步的(如 aiohttp),没必要再用 to_thread()。
6. 还有更好的方法吗?
有的!如果你只是在写爬虫或者请求 API,可以直接用 aiohttp,它是一个真正的异步 HTTP 库。

aiohttp 比 requests + asyncio.to_thread() 更快,因为它不需要额外的线程,是真正的异步网络请求库。
建议:如果你要做大量 HTTP 请求,直接用 aiohttp,别折腾 requests 了!
总结
• 同步请求会阻塞代码,异步请求可以并行执行,提高速度。
• 用 asyncio.to_thread() 可以让同步函数变成异步函数。
• 但如果是网络请求,建议直接用 aiohttp,它更快更高效!
异步编程是 Python 的一大亮点,掌握它可以让你的代码更高效、更现代化。希望这篇文章对你有所帮助!
以上就是“Python 异步编程入门:如何把同步函数变成异步函数?的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。



扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取