9.1 上下文管理器
还记得我们用with
语句来控制资源访问吗?利用它可以精确跟踪资源的使用时间和结束时间。这种方式也可以用于“异步资源”。
异步上下文管理器(AsyncContextManager)
用于在异步编程中管理资源,确保资源在异步函数中正确打开和关闭。它们的工作方式与普通上下文管理器类似,但设计用于在带有关键字async with
的异步函数中使用。
我就不详细讲这个啦,因为你们最近肯定不会自己创建异步上下文管理器,到时候也都忘了。不过我还是想让你们了解这个概念。
创建异步上下文管理器
异步上下文管理器使用__aenter__
和 __aexit__
方法来定义。这些方法类似于普通上下文管理器中的__enter__
和 __exit__
方法,但它们是异步的。
-
__aenter__()
: 进入上下文时调用的异步方法。 -
__aexit__(exc_type, exc, tb)
: 退出上下文时调用的异步方法。接受三个参数:异常类型、异常本身和追溯(traceback)
。
创建异步上下文管理器的例子
import asyncio
class AsyncContextManager:
async def __aenter__(self):
print("Enter context")
return self
async def __aexit__(self, exc_type, exc, tb):
print("Exit context")
async def main():
async with AsyncContextManager():
print("Inside context")
asyncio.run(main())
代码运行过程如下:
- 异步启动
main()
函数 main()
函数开始执行- 创建
AsyncContextManager
类型的对象 - 调用
AsyncContextManager
对象的__aenter__()
方法 - 打印
print("Enter context")
- 执行代码
print("Inside context")
- 调用
AsyncContextManager
对象的__aexit__()
方法 main()
函数执行完毕
9.2 使用示例
在上面的例子中,不一定要用异步版本的上下文管理器——即便用同步的代码也能正常工作。
但如果在with
块中
调用异步函数或
使用 await
运算符,那么异步管理器就是必需的。
用于文件操作的异步上下文管理器
这里我们用aiofiles
库来异步读写文件。异步上下文管理器aiofiles.open
可以安全地在异步环境中打开和关闭文件。
import aiofiles
import asyncio
async def main():
async with aiofiles.open('example.txt', mode='w') as file:
await file.write('Hello, world!')
asyncio.run(main())
用于网络操作的异步上下文管理器
这个例子使用aiohttp
库来执行异步HTTP请求。异步上下文管理器ClientSession
和session.get
提供了正确的连接管理。
import aiohttp
import asyncio
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
html = await fetch('https://example.com')
print(html)
asyncio.run(main())
异步上下文管理器提供了资源的自动管理,比如文件、网络连接和其他需要打开和关闭的资源。
__aenter__
和 __aexit__
方法允许在进入和退出上下文时执行异步操作,支持任务的并行执行。使用异步上下文管理器有助于避免资源泄露,并确保所有资源得到正确释放。
GO TO FULL VERSION