Как вызвать Exception, не прерывая цикл - PullRequest
0 голосов
/ 23 ноября 2018

Допустим, у меня есть какой-то прослушиватель событий, который должен работать все время, и есть некоторые exceptions, которые я хочу передать их вызывающей функции что-то вроде этого

import asyncio

_ = 0

async def listener(loop):
    while True:
        await asyncio.sleep(0.5)
        if _ != 0:
            raise ValueError('the _ is not 0 anymore!')
        print('okay')

async def executor(loop):
    while True:
        x = await loop.run_in_executor(None, input, 'execute: ')
        global _
        _ = x

async def main(loop):
    asyncio.ensure_future(listener(loop), loop=loop)
    await executor(loop)


loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))

, если вы собираетесь изменитьзначение, которое будет тормозить цикл события слушателя, но Я не хочу, чтобы оно break Я хочу, чтобы оно raise сообщало об ошибке, так что вы сможете его перехватить, а loop продолжать идти * 1010.*

1 Ответ

0 голосов
/ 24 ноября 2018

Я не хочу, чтобы он ломался. Я хочу, чтобы он выдавал ошибку, чтобы вы могли ее перехватить и цикл продолжился

Если вы хотите поднять ошибку, нопродолжайте, тогда слушатель не должен raise напрямую.Вместо этого он должен сигнализировать об исключении интересующимся сторонам, используя объект Future.Вместо того, чтобы ждать исполнителя, main() должен ожидать трансляцию будущего в цикле:

import asyncio

_ = 0
broadcast = None

async def listener():
    while True:
        await asyncio.sleep(0.5)
        if _ != 0:
            broadcast.set_exception(ValueError('the _ is not 0 anymore!'))
        else:
            print('okay')

async def executor():
    loop = asyncio.get_event_loop()
    while True:
        x = int(await loop.run_in_executor(None, input, 'execute: '))
        global _
        _ = x

async def main():
    global broadcast
    loop = asyncio.get_event_loop()
    loop.create_task(listener())
    loop.create_task(executor())
    while True:
        broadcast = loop.create_future()
        try:
            await broadcast
        except ValueError as e:
            print('got error', e)

asyncio.get_event_loop().run_until_complete(main())
...