Актуальна інформація:
Починаючи з Python 3.7 для цього була доданаasyncio.create_task(coro) функція високого рівня .
Ви повинні використовувати його замість інших способів створення завдань під час судового часу. Однак якщо вам потрібно створити завдання з довільно очікуваного, вам слід скористатися asyncio.ensure_future(obj).
Стара інформація:
ensure_future проти create_task
ensure_futureє метод створення Taskз coroutine. Він створює завдання різними способами, заснованими на аргументі (включаючи використання create_taskдля супротивників та майбутніх об'єктів).
create_taskє абстрактним методом AbstractEventLoop. Різні петлі подій можуть реалізувати цю функцію різними способами.
Ви повинні використовувати ensure_futureдля створення завдань. Вам знадобиться create_taskлише в тому випадку, якщо ви збираєтесь реалізувати власний тип циклу подій.
Оновлено:
@ bj0 вказав на відповідь Гідо на цю тему:
Сенс у ensure_future()тому, що якщо у вас є щось, що може бути або підпрограмою, або a Future(останній включає в себе а, Taskтому що це підклас Future), і ви хочете мати можливість викликати на ньому метод, який визначений лише Future(можливо, про єдиний корисний приклад буття cancel()). Коли це вже Future(або Task), це нічого не робить; коли це супровід, він загортає його в Task.
Якщо ви знаєте, що у вас є програма, і ви хочете, щоб це було заплановано, правильним API є create_task(). Єдиний час, коли вам слід дзвонити, ensure_future()- це коли ви надаєте API (як і більшість власних API API), який приймає або програму, або а, Futureі вам потрібно зробити щось для цього, що вимагає, щоб ви мали Future.
і пізніше:
Зрештою, я все-таки вважаю, що ensure_future()це належним чином незрозуміле ім'я для рідко потрібної функції. Створюючи завдання зі спільної програми, ви повинні використовувати відповідну назву
loop.create_task(). Може, для цього повинен бути псевдонім
asyncio.create_task()?
Для мене це дивно. Моя основна мотивація використовувати ensure_futureвесь час - це функція вищого рівня порівняно з членом циклу create_task(обговорення містить деякі ідеї, такі як додавання asyncio.spawnчи asyncio.create_task).
Я також можу зазначити, що на мою думку, досить зручно використовувати універсальну функцію, яка може справлятись лише з будь-якими, Awaitableа не з супроводуми.
Однак відповідь Гвідо зрозуміла: "Створюючи завдання за допомогою програми, ви повинні використовувати відповідне ім'я loop.create_task()"
Коли спільні програми слід обертати завданнями?
Загортання програми в завдання - це спосіб запустити цю програму "у фоновому режимі". Ось приклад:
import asyncio
async def msg(text):
await asyncio.sleep(0.1)
print(text)
async def long_operation():
print('long_operation started')
await asyncio.sleep(3)
print('long_operation finished')
async def main():
await msg('first')
# Now you want to start long_operation, but you don't want to wait it finised:
# long_operation should be started, but second msg should be printed immediately.
# Create task to do so:
task = asyncio.ensure_future(long_operation())
await msg('second')
# Now, when you want, you can await task finised:
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Вихід:
first
long_operation started
second
long_operation finished
Ви можете замінити, щоб asyncio.ensure_future(long_operation())просто await long_operation()відчути різницю.
create_taskякщо вам дійсно потрібен об'єкт завдання, який вам зазвичай не потрібен: github.com/python/asyncio/isissue/477#issuecomment-268709555