Aktualne informacje:
Począwszy od Pythona 3.7 dodano w tym celu asyncio.create_task(coro)funkcję wysokiego poziomu .
Powinieneś użyć go zamiast innych sposobów tworzenia zadań z coroutimes. Jeśli jednak chcesz utworzyć zadanie z dowolnego oczekiwanego, powinieneś użyć asyncio.ensure_future(obj).
Stare informacje:
ensure_future vs create_task
ensure_futureJest to sposób, aby utworzyć Taskz coroutine. Tworzy zadania na różne sposoby w oparciu o argumenty (w tym użycie create_taskdla programów i obiektów przyszłościowych).
create_taskjest abstrakcyjną metodą AbstractEventLoop. Różne pętle zdarzeń mogą implementować tę funkcję na różne sposoby.
Do ensure_futuretworzenia zadań należy używać . Będziesz potrzebny create_tasktylko wtedy, gdy zamierzasz zaimplementować własny typ pętli zdarzeń.
Aktualizacja:
@ bj0 wskazał na odpowiedź Guido na ten temat:
Chodzi o ensure_future()to, że jeśli masz coś, co może być albo coroutine, albo a Future(ta ostatnia zawiera a, Taskponieważ jest to podklasa Future), i chcesz mieć możliwość wywołania metody, która jest zdefiniowana tylko w Future(prawdopodobnie jedynej przydatnym przykładem jest cancel()). Kiedy już jest Future(lub Task) to nic nie robi; kiedy jest to program, zawija go w plik Task.
Jeśli wiesz, że masz program i chcesz, aby został on zaplanowany, odpowiednim interfejsem API jest create_task(). Jedynym momentem, w którym powinieneś wywoływać, ensure_future()jest dostarczanie API (jak większość własnych interfejsów API asyncio), które akceptuje coroutine lub a Futurei musisz zrobić z nim coś, co wymaga posiadania pliku Future.
i później:
W końcu nadal uważam, że ensure_future()jest to odpowiednio mało znana nazwa rzadko potrzebnego elementu funkcjonalności. Tworząc zadanie z programu, należy skorzystać z odpowiednio nazwanego
loop.create_task(). Może powinien być do tego alias
asyncio.create_task()?
To dla mnie zaskakujące. Moją główną motywacją do używania przez ensure_futurecały czas było to, że jest to funkcja wyższego poziomu w porównaniu do elementu członkowskiego pętli create_task(dyskusja zawiera kilka pomysłów, takich jak dodawanie asyncio.spawnlub asyncio.create_task).
Mogę również wskazać, że moim zdaniem dość wygodne jest użycie uniwersalnej funkcji, która obsługuje dowolne, Awaitablea nie tylko programy.
Jednak odpowiedź Guido jest jasna: „Tworząc zadanie z poziomu programu, należy użyć odpowiednio nazwanego loop.create_task()”
Kiedy programy powinny być opakowane w zadania?
Wrap coroutine in a Task - to sposób na uruchomienie tego programu „w tle”. Oto przykład:
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')
task = asyncio.ensure_future(long_operation())
await msg('second')
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Wynik:
first
long_operation started
second
long_operation finished
Możesz zastąpić asyncio.ensure_future(long_operation())go tylko await long_operation()po to, aby poczuć różnicę.
create_taskjeśli naprawdę potrzebujesz obiektu zadania, którego normalnie nie potrzebujesz: github.com/python/asyncio/issues/477#issuecomment-268709555