aiohttp做request时await和async-with有本质区别吗?

Is there an essential difference between await and async-with while doing request in aiohttp?

我的问题是关于在 aiohttp

中做出回应的正确方式

aiohttp 官方文档为我们提供了进行异步查询的示例:

session = aiohttp.ClientSession()

async with session.get('http://httpbin.org/get') as resp:
    print(resp.status)
    print(await resp.text())

await session.close()

我不明白,为什么上下文管理器在这里。我所发现的只是 __aexit__() 方法等待 resp.release() 方法。但是文档还告诉我们通常不需要等待 resp.release()

这一切让我很困惑。

如果我发现下面的代码更具可读性并且没有那么嵌套,我为什么要那样做?

session = aiohttp.ClientSession()

resp = await session.get('http://httpbin.org/get')
print(resp.status)
print(await resp.text())

# I finally have not get the essence of this method.
# I've tried both using and not using this method in my code,
# I've not found any difference in behaviour.
# await resp.release()

await session.close()

我已经深入研究了 aiohttp.ClientSession 及其上下文管理器的来源,但我还没有找到任何可以澄清情况的信息。

最后,我的问题:有什么区别?

通过 async with 明确管理响应不是必需的,但建议这样做。 async with 用于响应对象的目的是 安全迅速地 释放响应所使用的资源(通过调用 resp.release())。也就是说,即使发生错误,资源也会被释放并可用于进一步 requests/responses.

否则,aiohttp也会释放响应资源,但不保证及时性。最坏的情况是延迟任意时间,即直到应用程序结束和外部资源(如套接字)超时。


如果没有错误发生,差异不明显(在这种情况下 aiohttp 清理未使用的资源)and/or 如果应用程序很短(在这种情况下有足够的资源不需要重新-采用)。但是,由于错误可能会意外发生并且 aiohttp 是为许多 requests/responses 设计的,因此建议 总是 默认通过 async with 提示清理。