全部文章

with 语句的本质

在 Python 中,with 语句是一个用于资源管理的语法结构,它通过上下文管理器(Context Manager)自动处理资源的获取和释放(如文件、网络连接、锁等)。而 async with 是其异步版本,专为异步编程设计。以下是详细解析:


1. with 语句的本质

  • with 不是方法,而是一个语法结构,它的底层依赖于对象的 __enter__ 和 __exit__ 方法。

  • 作用:确保资源在使用后被正确清理,避免资源泄漏。

同步 with 语句的等效代码

# 写法1:标准 with 语法
with open("file.txt") as f:
    data = f.read()

# 写法2:等效的 try-finally 结构
f = open("file.txt")
try:
    data = f.read()
finally:
    f.close()

2. 上下文管理器的实现原理

任何实现了 __enter__ 和 __exit__ 方法的对象都可以作为上下文管理器。

自定义同步上下文管理器

class mywith():
    def __init__(self,filename,type,encode):
        self.filename = filename
        self.type = type
        self.encode = encode
    def __enter__(self):
        self.file = open(self.filename,self.type,encoding=self.encode)
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

with mywith('../tem/test.txt','r',"utf-8") as f:
    for line in f:
        print(line)

3. 异步上下文管理器 (async with)

在异步编程中,资源的获取和释放可能是异步操作(如网络请求、数据库连接),此时需使用 async with 和异步上下文管理器。

异步上下文管理器的实现

异步上下文管理器需实现 __aenter__ 和 __aexit__ 方法(注意 async def):

class AsyncFileManager:
    def __init__(self, filename):
        self.filename = filename

    async def __aenter__(self):
        self.file = await aiofiles.open(self.filename, mode='r')  # 异步打开文件
        return self.file

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.file.close()  # 异步关闭文件

# 使用
async with AsyncFileManager("data.txt") as f:
    content = await f.read()

4. with 和 async with 的对比

特性with(同步)async with(异步)
上下文方法 __enter__ 和 __exit__ __aenter__ 和 __aexit__
是否需要等待 是(需 await
适用场景 同步资源管理(如文件、锁) 异步资源管理(如 HTTP 连接、异步文件)
依赖库示例 open()threading.Lock() aiohttp.ClientSession()aiofiles.open()

posted @ 2025-03-28 09:38  指尖下的世界  阅读(17)  评论(0)    收藏  举报