异步编程在Python语言中从3.5版本开始引入,通过关键字async和await实现。最初,异步任务通过像asyncio这样的库和基于协程的生成器来实现,这使得理解和维护变得复杂。随着async/await语法的出现,异步代码变得更加明确和可读,接近于常规的同步风格。
在async/await出现之前,异步性是通过回调和生成器实现的(例如,通过tornado库或旧的asyncio API)。这样的代码难以调试和维护。
在处理大量并发I/O操作(网络请求、文件输入/输出)时,同步代码的主要问题是阻塞主线程。这导致性能下降,无法有效利用资源。
使用async/await的异步编程允许在单线程内并行执行多个输入输出操作,避免阻塞。在此过程中,语法类似于常规函数,这提高了可读性和调试性。
import asyncio async def fetch_data(delay): print(f"开始在{delay}s延迟后获取数据") await asyncio.sleep(delay) print(f"完成在{delay}s延迟后获取数据") return delay async def main(): results = await asyncio.gather( fetch_data(1), fetch_data(2), fetch_data(3) ) print("结果:", results) asyncio.run(main())
用async def定义的函数能否像普通函数一样被调用?
不行。调用这样的函数会返回一个协程对象,直到将其传递给事件循环(例如,通过await或asyncio.run())之前不会执行。
def foo(): return 42 async def bar(): return 42 print(foo()) # 42 print(bar()) # <coroutine object bar at ...>
可以在异步函数之外使用await吗?
不行。关键字await只能在使用async def声明的函数内部使用。在这样的函数外部使用await将引发SyntaxError。
# 错误! await asyncio.sleep(1) # SyntaxError: 'await' outside async function
异步性是否适用于与I/O无关的操作(例如计算)?
不行。异步性仅对输入输出操作有效。对于计算任务,仍然需要使用multiprocessing或threading,否则事件循环将被阻塞。
优点:
缺点:
负面案例: 年轻的开发者通过async/await来加速应用程序,但异步执行的只是计算,而不是网络请求。应用程序没有加速。优点:接触了语法。缺点:没有收益,代码复杂了。
正面案例: 异步处理了成千上万的API请求。服务器在没有增加资源的情况下服务了更多客户。优点:性能显著提升,架构变得更简单。缺点:新手的入门门槛提高。