Как создать задачу asyncio, которая возвращает значение?

#python #async-await #return #python-asyncio #telethon

#python #асинхронный-ожидание #Возврат #python-асинхронный #телемарафон

Вопрос:

Я выясняю, как вернуть список [] в asyncio Я знаю asyncio.gather , что это могло бы мне помочь, но есть так много способов, которыми я сейчас в замешательстве. Как мне вернуть значение из main() ? Спасибо

 async def wait_until(dt):
    # sleep until the specified datetime
    now = datetime.now()
    await asyncio.sleep((dt - now).total_seconds())

async def run_at(dt, coro):
    await wait_until(dt)
    return await coro

async def main():
    test=[]
    async for message in client.iter_messages(channel):
        test.append(message)
        return test


loop = asyncio.get_event_loop()
loop.create_task(run_at(datetime(2020, 12, 29, 19, 17),main()))
loop.run_until_complete(asyncio.gather(*[main()]))
# How to get test[] or How to pass it to another task?
loop.run_forever()
 

Комментарии:

1. Я буду использовать глобальный var, но я уверен, что есть лучший способ сделать это. Кроме того, знаете ли вы, что возвращаетесь test[] после первого цикла?

Ответ №1:

Из asyncio.gather документации:

Если все ожидаемые параметры завершены успешно, результатом является сводный список возвращаемых значений. Порядок значений результатов соответствует порядку ожидаемых значений в aws.

Из asyncio.loop.run_until_complete документации:

Верните результат Future или вызовите его исключение.

So gather async def — это то, что возвращает все переданные результаты и run_until_complete запускает цикл «преобразования» ожидаемого в результат. По сути, возвращаемые значения передаются через:

 results = loop.run_until_complete(asyncio.gather(*[main()]))
tests = results[0]
 

Обратите внимание, что gather использование только одного элемента является избыточным, так как это эквивалентно простому использованию этого одного элемента:

 tests = loop.run_until_complete(main())
 

Если вы хотите связать две независимые задачи без использования глобальных переменных, вы, вероятно, захотите использовать an asyncio.Queue и предоставить один и тот же экземпляр очереди обоим async def в качестве входных параметров. Один будет put «сообщения», а другой get — их.

Вы можете комбинировать это с wait , gather , create_task , и т.д., чтобы в значительной степени сделать все, что вам нужно.