上下文管理器(同步&异步)
异步上下文管理器(async with
)和同步上下文管理器(with
)的区别主要在于它们的工作方式与事件循环的配合。理解这一点可以帮助你更好地使用它们处理 I/O 操作,尤其是在异步编程中。以下是两者的主要区别:
工作方式#
-
同步上下文管理器 (
with
):- 同步上下文管理器用于同步代码块,它会在进入
with
块时执行__enter__
方法,并在退出with
块时执行__exit__
方法。 - 在
with
块中,所有操作是同步的,程序会按顺序执行,不会立即返回,直到with
块中的代码执行完毕。 - 示例:文件操作、数据库连接、线程锁等常见同步操作。
with open('example.txt', 'r') as file: content = file.read() # 这里的代码是同步的,程序会等待文件操作完成才继续执行
- 同步上下文管理器用于同步代码块,它会在进入
-
异步上下文管理器 (
async with
):- 异步上下文管理器用于异步编程,它同样具有
__enter__
和__exit__
方法,但是它们是异步的(使用async def
定义),并且需要使用await
来等待其完成。 - 这意味着它适用于 I/O 密集型的操作,比如网络请求、数据库查询或文件操作等,它们可以并发执行,而不会阻塞事件循环。
- 使用
async with
时,进入和退出上下文时的操作是异步执行的,因此它允许在等待 I/O 操作完成时执行其他任务。
import aiofiles async with aiofiles.open('example.txt', 'r') as file: content = await file.read() # 这里的代码是异步的,程序会在等待文件操作时执行其他任务
- 异步上下文管理器用于异步编程,它同样具有
应用场景#
-
同步上下文管理器 (
with
):- 适用于执行一些需要阻塞等待的操作,比如读取文件、访问数据库或进行一些需要锁定资源的操作(如多线程中的锁)。
- 在同步编程中,
with
是非常常见的。
-
异步上下文管理器 (
async with
):- 主要用于 I/O 密集型的操作,特别是当操作会导致等待(如网络请求、文件系统操作、数据库查询等)时。
- 使用
async with
可以避免在等待 I/O 操作时阻塞主线程,从而提高程序的效率和响应性。 - 例如,在
aiohttp
(异步 HTTP 请求)或aiofiles
(异步文件操作)中,我们通常会使用async with
。
如何实现#
-
同步上下文管理器:
- 通过实现
__enter__
和__exit__
方法来定义上下文管理器的行为。
示例:
class MyContextManager: def __enter__(self): print("Enter") return self def __exit__(self, exc_type, exc_val, exc_tb): print("Exit") with MyContextManager() as manager: print("Inside the context") # Output: # Enter # Inside the context # Exit
- 通过实现
-
异步上下文管理器:
- 通过实现
__aenter__
和__aexit__
方法来定义异步上下文管理器的行为。
示例:
class MyAsyncContextManager: async def __aenter__(self): print("Async Enter") return self async def __aexit__(self, exc_type, exc_val, exc_tb): print("Async Exit") import asyncio async def main(): async with MyAsyncContextManager() as manager: print("Inside the async context") asyncio.run(main()) # Output: # Async Enter # Inside the async context # Async Exit
- 通过实现
性能差异#
-
同步上下文管理器:
- 在执行 I/O 操作时,程序会被阻塞,直到操作完成。例如,如果在文件读取过程中等待,整个程序将停下来,直到文件内容被读取完。
-
异步上下文管理器:
- 异步上下文管理器允许你在等待 I/O 操作的同时,执行其他任务。对于大量 I/O 密集型操作,这会显著提高程序的效率,因为它避免了阻塞操作。
常见使用库#
- 同步上下文管理器:
open
(文件操作)、threading.Lock
(线程锁)、sqlite3.connect
(数据库连接)等。 - 异步上下文管理器:
aiohttp.ClientSession
(异步 HTTP 请求)、aiofiles.open
(异步文件操作)等。
总结#
- 同步上下文管理器(
with
)适用于同步的、阻塞的操作,它等待一个操作完成后才进行下一个操作。 - 异步上下文管理器(
async with
)适用于异步编程,可以在等待 I/O 操作时允许程序执行其他任务,从而提高效率。
简而言之,选择 with
还是 async with
,取决于你是在处理同步操作还是异步操作。在 I/O 密集型的异步场景下,推荐使用异步上下文管理器来避免阻塞。
作者:cloud-2-jane
出处:https://www.cnblogs.com/cloud-2-jane/articles/18620663
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架