Единственное заметное преимущество асинхронных итераторов / контекстных менеджеров, на которые я обращаю внимание, состоит в том, что вы можете использовать awaitables в реализациях их требуемых магических методов. Я что-то упускаю или это всё?
Вы ничего не упускаете, кроме, возможно, значимости способности приостановить. Без подвешенных магических методов контекстные менеджеры и итераторы были бы бесполезны для асинхронной работы. Например, обычный файловый объект служит в качестве итератора, который создает строки из файла. Чтобы асинхронный файловый объект (или поток) предоставил эквивалентную функциональность, он должен быть в состоянии ожидать появления строки и, таким образом, приостанавливать сопрограмму, выполняющую итерации по ней. То же самое относится к диспетчеру контекста, при входе которого должно быть установлено асинхронное сетевое соединение и т. Д.
Имеет ли [возможность приостановить выполнение] обращение к вызывающим сопрограммам с использованием await?
Использование await
в async def
- это один из способов приостановить выполнение. Другой вариант для __aenter__
и т. Д. Должен быть обычными функциями, которые возвращают ожидаемый пользовательский объект, который реализует свой собственный __await__
. PEP 492 описывает функциональные возможности с точки зрения кода, который использует менеджер контекста, который должен быть готов к тому, что его магические методы будут приостановлены - async with
должен быть внутри async def
, и он будет десагарен, чтобы кодировать await
в соответствующих местах.