D. Anderson
D. Anderson

Reputation: 75

Seeking explanation of the advantages of async with/for

I'm new to asyncio. I came across AIOFiles (https://github.com/Tinche/aiofiles) recently and saw in the documentation that it supports 'async with' and 'async for.' I wanted to learn about it but there isn't much good coverage on it besides PEP 492 which doesn't go into too much detail.

Shortcuts to the relevant sections of PEP 492:

https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with

https://www.python.org/dev/peps/pep-0492/#asynchronous-iterators-and-async-for

I have a number of questions if somebody wouldn't mind answering:

  1. The only discernible benefit of async iterators / context managers I am picking up on is that you can use awaitables in the implementations of their required magic methods. Am I missing something or is that it?

  2. In PEP 492 regarding async context manager, it says "An asynchronous context manager is a context manager that is able to suspend execution in its enter and exit methods." Is this referring to calling coroutines using await?

Upvotes: 1

Views: 371

Answers (1)

user4815162342
user4815162342

Reputation: 155610

The only discernible benefit of async iterators / context managers I am picking up on is that you can use awaitables in the implementations of their required magic methods. Am I missing something or is that it?

You're not missing anything, except perhaps the significance of the ability to suspend. Without suspendable magic methods, context managers and iterators would be useless for async work. For example, a regular file object serves as an iterator that produces the lines from the file. For an async file object (or a stream) to provide equivalent functionality, it must be able to await the line to come, and thereby suspend the coroutine that iterates over it. The same applies to a context manager whose entering must establish an async network connection, and so on.

Is [being able to suspend execution] referring to calling coroutines using await?

Using await in an async def is one way to suspend execution. Another option is for __aenter__ etc. to be normal functions that return a custom awaitable that implements its own __await__. PEP 492 describes the functionality from the vantage point of the code that uses the context manager, which must be ready for its magic methods to suspend -- async with must be inside an async def and it will desugar to code that awaits in the appropriate places.

Upvotes: 1

Related Questions