Допустим, у нас есть фиктивная функция:
async def foo(arg):
result = await some_remote_call(arg)
return result.upper()
Какая разница между:
import asyncio
coros = []
for i in range(5):
coros.append(foo(i))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(coros))
И:
import asyncio
futures = []
for i in range(5):
futures.append(asyncio.ensure_future(foo(i)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(futures))
Примечание . Пример возвращает результат, но вопрос не в этом. Когда значение возврата имеет значение, используйтеgather()
вместо wait()
.
Независимо от возвращаемого значения, я ищу ясности ensure_future()
. wait(coros)
иwait(futures)
оба запускают сопрограммы, поэтому когда и почему сопрограмму следует обернуть вensure_future
?
В принципе, каков правильный способ (TM) запускать кучу неблокирующих операций с использованием Python 3.5 async
?
Что делать, если я хочу группировать звонки в качестве дополнительного кредита? Например, мне нужно позвонить some_remote_call(...)
1000 раз, но я не хочу раздавить веб-сервер / базу данных и т. Д. 1000 одновременных подключений. Это можно сделать с потоком или пулом процессов, но есть ли способ сделать это с помощью asyncio
?
Обновление 2020 (Python 3.7+) : не используйте эти фрагменты. Вместо этого используйте:
import asyncio
async def do_something_async():
tasks = []
for i in range(5):
tasks.append(asyncio.create_task(foo(i)))
await asyncio.gather(*tasks)
def do_something():
asyncio.run(do_something_async)
Также рассмотрите возможность использования Trio , надежной сторонней альтернативы asyncio.
ensure_future()
? И если мне нужен результат, нельзя ли просто использоватьrun_until_complete(gather(coros))
?