文章摘要
Python自2015年引入async和await关键字以来,异步编程功能已有十年历史,但并未广泛流行。尽管Python 3.14即将发布,带来了新的并发和并行特性,如PEP779的自由线程支持和PEP734的多解释器功能,社区对异步编程的接受度仍有限。
文章总结
Python异步编程十年:为何仍未普及?
Python 3.5在2015年引入了async和await关键字,用于执行协程。然而,十年过去了,异步编程在Python社区中仍未广泛普及。尽管Python 3.14即将发布,带来了诸如自由线程(Free-Threading)和多解释器(Multiple Interpreters)等重大并发和并行特性,但异步编程的普及度仍然有限。
异步编程的主要应用场景是Web开发,尤其是在处理网络请求和数据库查询等I/O密集型任务时,协程能够显著提升性能。然而,尽管异步编程在理论上具有优势,但在实际应用中,许多开发者仍然倾向于使用同步编程模型。例如,Python中最流行的Web框架之一Django,虽然已经支持异步编程,但其ORM(对象关系映射)等关键部分仍在开发中。而另一个流行的框架Flask则始终是同步的,尽管有异步替代品Quart,但其API与Flask相似。
异步编程的普及度受限的原因主要有以下几点:
异步编程的复杂性:异步编程模型对于没有网络编程背景的开发者来说并不直观。开发者容易忘记使用
await关键字,导致函数未执行,或者在使用协程时未正确传递参数,导致错误无法及时捕获。相比之下,线程模型更容易理解和使用。GIL(全局解释器锁)的限制:Python的GIL使得多线程编程在CPU密集型任务中无法充分利用多核性能。尽管异步编程在I/O密集型任务中表现优异,但在CPU密集型任务中,异步编程的优势并不明显。此外,GIL的存在使得Python的多线程编程在性能上受到限制。
异步编程的适用场景有限:异步编程在处理网络I/O时表现出色,但在文件I/O等操作中,异步编程的支持并不完善。尽管可以通过第三方库(如
aiofiles)实现异步文件操作,但这些库通常依赖于线程池来处理阻塞操作,无法真正实现异步。维护同步和异步API的复杂性:对于库和框架的维护者来说,同时支持同步和异步API是一项巨大的挑战。许多标准库并不原生支持异步编程,且Python的魔法方法(如
__init__)无法异步化,这限制了异步编程的应用范围。
尽管异步编程在Python中的普及度有限,但它在某些领域仍然取得了成功。例如,FastAPI作为一个从头开始设计为异步的Web框架,其市场份额从29%增长到38%,成为Python中最受欢迎的Web框架之一。这表明,在HTTP和网络I/O等主要应用场景中,异步编程仍然具有巨大的潜力。
展望未来,Python 3.14的自由线程和多解释器特性有望为并行和并发编程带来更多可能性。这些新特性可能会减少对异步API的依赖,并缓解当前异步编程面临的一些问题。随着这些新特性的逐步成熟,Python的并发编程模型可能会迎来新的发展机遇。
总之,尽管异步编程在Python中已经存在了十年,但其普及度仍然有限。随着新特性的引入,Python的并发编程模型可能会在未来几年内发生显著变化。
评论总结
主要观点总结:
异步编程的复杂性和调试困难
- 许多评论者认为Python的异步编程(async)难以使用和调试,容易陷入随机卡顿和竞态条件问题。
- 引用:
- "Python's async is very difficult to use and debug. It seems to get stuck randomly, read like race conditions." (dapperdrake)
- "async feels like surprise goto. async feels like it accepts a request, and then will at some point at the future either trigger more async, or crap out mixing loads of state from different requests all over the place." (KaiserPro)
异步与同步API的不兼容性
- 异步代码与现有同步代码库不兼容,导致需要重写整个代码库才能获得性能提升。
- 引用:
- "The two api issue basically means async is not backwards compatible. You can't just squeeze some async into an existing code base." (ketchupdebugger)
- "its infectious. You need to wrap everything in async or nothing." (KaiserPro)
异步编程的普及度和历史原因
- 异步编程在Python中的普及度较低,部分原因是历史遗留问题(如WSGI的长期存在)以及其他语言(如JavaScript)的竞争。
- 引用:
- "WSGI has been around a while before async became relevant." (giancarlostoro)
- "async was too little, too late. By the time it was introduced, most people who actually needed to do lots of io concurrently had their own workarounds." (atomicnumber3)
异步编程的潜在优势
- 尽管存在争议,部分开发者认为异步编程在处理I/O密集型任务时具有优势,尤其是在网络编程中。
- 引用:
- "Coming from a networking background, the way I can deal with I/O has been massively simplified, and coroutines are quite useful." (rcarmo)
- "async is faster in a lot of cases." (KaiserPro)
异步编程的替代方案
- 许多开发者更倾向于使用线程、进程或其他并发模型(如gevent、greenlets)来替代异步编程。
- 引用:
- "I always liked gevent/eventlet based approach and will likely always stick to using that." (rdtsc)
- "If I wanted something super performant I wouldn't be using python in the first place." (bmandale)
异步编程的标准化和文档问题
- 异步编程缺乏标准化和清晰的文档,导致开发者难以入门和正确使用。
- 引用:
- "There should be one-- and preferably only one --obvious way to do it." (tschellenbach)
- "Python's async might have been one unit more popular if it had had any documentation." (mjd)
总结:
Python的异步编程在性能和I/O处理方面具有潜力,但其复杂性、调试困难、与现有代码库的不兼容性以及缺乏标准化和文档,导致许多开发者对其持保留态度。许多开发者更倾向于使用线程、进程或其他并发模型,或者选择其他语言(如JavaScript、Go)来处理并发任务。