Как вырваться из asyncio coroutine без использования оператора "return"?
Я немного затрудняюсь решить, как выйти из этой сопрограммы, если оператор except
поймает. Обычно я просто использую:
def f(x):
try:
foo_var = next(a_volitile_generator(x))
except Exception:
print('it broked')
return
yield foo_var
Однако! Я собираюсь породить газиллион этих генераторных функций, сделать их сопрограммами и, наконец, Future
из них и загрузить их в цикл событий. Вот в чем проблема:
loop = asyncio.get_event_loop()
queue = asyncio.Queue(maxsize=100)
async def f(x, result_queue, *, loop=loop):
while _some_condition() is True:
try:
foo_var = await a_volitile_async_generator(x)
except Exception:
print('it broked')
# HELP BELOW
raise StopAsyncIteration # <--ONLY OPTION????????
await result_queue.put(foo_var)
Возврат чего-либов цикл событий -это нет-нет в asyncio
, потому что вы все сломаете...даже если это значение равно None
.
В сторону исходя из этого, давайте также скажем, что я хотел бы избежать повышения StopAsyncIteration
...Я пытаюсь понять, является ли это единственным способом сделать это или у меня есть другие варианты:
2 ответа:
Как упомянуто @dirn в комментариях, вы можете заменить свою
raise StopAsyncIteration
строку на простуюbreak
:async def f(x, result_queue, *, loop=loop): while _some_condition() is True: try: foo_var = await a_volitile_async_generator(x) except Exception: print('it broked') break await result_queue.put(foo_var)
Джонни, я думаю, ты делаешь что-то не так.
yield from a_volitile_async_generator(x)
Если
a_volitile_async_generator
является реальным асинхронным генератором, он не будет работать: Вы не можете использоватьyield from
вместе с ним.