Я все еще изучаю основы асинхронного питона, и некоторые вещи меня смущают.
import asyncio
loop=asyncio.get_event_loop()
for variation in args:
loop.create_task(coroutine(variation))
loop.run_forever()
Кажется очень похожим на это
import asyncio
loop=asyncio.get_event_loop()
loop.run_forever(
asyncio.gather(
coroutine(variation_1),
coroutine(variation_2),
...))
Они могут делать то же самое, но это не кажется полезным, так в чем разница?





Как упоминалось в комментариях, ваш второй пример должен использовать run_until_complete, а не run_forever.
They might do the same thing, but that doesn't seem useful, so what's the difference?
asyncio.gather - это конструкция более высокого уровня.
create_task отправляет сопрограмму в цикл событий, эффективно позволяя ей работать «в фоновом режиме» (при условии, что сам цикл событий активен). Как следует из названия, он возвращает задача, дескриптор выполнения сопрограммы, что наиболее важно, предоставляя возможность Отмена. Вы можете создать любое количество таких задач в цикле событий, и все они будут выполняться до их соответствующего завершения.
asyncio.gather используется, когда вас действительно интересует полученные результаты сопрограмм, которые вы создали. Он порождает их, как если бы с create_task, позволяя им работать параллельно, но также ожидает их завершения, а затем возвращает их соответствующие результаты (или вызывает исключение, если какой-либо из них вызвал один).
Например, если у вас есть сопрограмма download, которая загружает URL-адрес и возвращает его содержимое, и вы загружаете список URL-адресов, gather позволяет вам сопоставить URL-адреса с их данными:
url_list = [...]
data_list = await asyncio.gather(*[download(url) for url in url_list]
# url_list and data_list now have matching elements, so this works:
for url, data in zip(url_list, data_list):
...
Сделать это с помощью только create_task было бы намного сложнее.
gather также позволяет отменить все задачи одной командой cancel().
@AviahLaor Да, но будьте осторожны, потому что бывают случаи, когда это не работает как ожидалось.
run_foreverне принимает аргументов. Ваш второй пример должен использоватьrun_until_complete.