Если вам разрешено изменять R99
, вы можете заставить __await__()
вызывать фактическую сопрограмму, которая может последовательно соединяться с super()
:
import asyncio
class R99:
async def await_coro(self):
loop = asyncio.get_event_loop()
fut = loop.create_future()
loop.call_later(0.5, fut.set_result, 99)
return await fut
def __await__(self):
return self.await_coro().__await__()
class R100(R99):
async def await_coro(self):
v = await super().await_coro()
return v + 1
Если это неВариант, ответ @ Vincent точно объясняет, как соединиться от одного __await__
к другому.Обратите внимание, что вы были совершенно правы, считая, что await
- это новый yield from
- так оно и есть, и обычно нет причин использовать yield from
во вновь написанном асинхронном коде.(Это, конечно, не относится к генераторам, не связанным с асинхронностью, которые делегируют субгенераторам; они могут продолжать использовать yield from
.)
Однако, внедрив __await__()
, вы переходите вAPI нижнего уровня, который использует генераторы для реализации сопрограмм.На этом уровне yield
приостанавливает сопрограмму, возвращая управление в цикл событий, и yield from
делегирует другому генератору, который реализует сопрограмму.В новом коде единственной допустимой целью для этого уровня является реализация ожидаемого объекта без использования интерпретатора, например, в Python / C или Cython.Это делается путем предоставления __await__
, который возвращает итератор, как показано здесь .Полученный объект эквивалентен async def
.