Я не думаю, что кто-то конкретно обсуждал это как явный выбор дизайна при обсуждении PEP 492 , но я думаю, что это не просто , когда они делятся значительным кодом, но также и то, что они должны быть настолько взаимозаменяемыми, насколько это возможно. Если какая-то другая реализация Python по какой-то причине строит async
coros и yield from
coros по-разному, они все равно должны быть такими же взаимозаменяемыми, как и в CPython (так что, например, вы можете запустить asyncio
код, написанный для Python 3.4).
Во всяком случае, даже если обоснование нигде не закреплено в столь многих словах, решение явно задокументировано в PEP под Методы объекта сопрограммы :
Сопрограммы основаны на генераторах внутри, поэтому они разделяют реализацию. Подобно объектам-генераторам, сопрограммы имеют методы throw()
, send()
и close()
. StopIteration
и GeneratorExit
играют одинаковую роль для сопрограмм ...
И еще одна вещь, которую сделал , как часть обсуждения async for
, заключается в том, что асинхронный итератор не может вызвать StopIteration
. И если бы дизайн каким-то образом изменился, чтобы асинхронные итераторы могли его поднять, это сделало бы невозможным создание асинхронных итераторов с обычными генераторами. Итак, новое исключение StopAsyncIteration
было создано. В этот момент стало ясно, что на самом деле не существует случая, когда coro или нормальный генератор явно повышают StopIteration
, следовательно, PEP 479 (который был применен к асинхронному coros немедленно, но был обнаружен в течение нескольких версии для традиционных генераторов). См. Почему StopAsyncIteration
.