Info sebenarnya:
Mulai dari asyncio.create_task(coro)
fungsi tingkat tinggi Python 3.7 ditambahkan untuk tujuan ini.
Anda harus menggunakannya sebagai ganti cara lain untuk membuat tugas dari coroutimes. Namun jika Anda perlu membuat tugas dari arbitrary awaitable, Anda harus menggunakan asyncio.ensure_future(obj)
.
Info lama:
ensure_future
vs. create_task
ensure_future
adalah metode untuk membuat Task
dari coroutine
. Ini membuat tugas dengan cara berbeda berdasarkan argumen (termasuk penggunaan create_task
for coroutine dan objek seperti masa depan).
create_task
adalah metode abstrak AbstractEventLoop
. Perulangan peristiwa yang berbeda dapat mengimplementasikan fungsi ini dengan cara yang berbeda.
Anda harus menggunakan ensure_future
untuk membuat tugas. Kamu akan membutuhkancreate_task
hanya jika Anda akan mengimplementasikan jenis loop acara Anda sendiri.
Pembaruan:
@ bj0 menunjuk jawaban Guido tentang topik ini:
Intinya ensure_future()
adalah jika Anda memiliki sesuatu yang bisa berupa coroutine atau a Future
(yang terakhir menyertakan a Task
karena itu adalah subkelas dari Future
), dan Anda ingin dapat memanggil metode di atasnya yang hanya ditentukan di Future
(mungkin tentang satu-satunya contoh yang berguna cancel()
). Jika sudah menjadi Future
(atau Task
) ini tidak melakukan apa-apa; ketika itu adalah coroutine itu membungkusnya dalam a Task
.
Jika Anda mengetahui bahwa Anda memiliki coroutine dan Anda ingin menjadwalkannya, API yang tepat untuk digunakan adalah create_task()
. Satu-satunya saat Anda harus menelepon ensure_future()
adalah saat Anda menyediakan API (seperti kebanyakan API asyncio sendiri) yang menerima coroutine atau a Future
dan Anda perlu melakukan sesuatu yang mengharuskan Anda memiliki Future
.
dan nanti:
Pada akhirnya saya masih percaya itu ensure_future()
adalah nama yang tidak jelas untuk fungsionalitas yang jarang dibutuhkan. Saat membuat tugas dari coroutine, Anda harus menggunakan nama yang sesuai
loop.create_task()
. Mungkin harus ada alias untuk itu
asyncio.create_task()
?
Ini mengejutkan saya. Motivasi utama saya untuk menggunakannya ensure_future
selama ini adalah fungsi tingkat yang lebih tinggi dibandingkan dengan anggota loop create_task
(diskusi berisi beberapa ide seperti menambahkan asyncio.spawn
atau asyncio.create_task
).
Saya juga dapat menunjukkan bahwa menurut saya cukup nyaman menggunakan fungsi universal yang dapat menangani apa saja Awaitable
daripada hanya coroutine.
Namun, jawaban Guido jelas: "Saat membuat tugas dari coroutine Anda harus menggunakan nama yang tepat loop.create_task()
"
Kapan coroutine harus dibungkus dalam tugas?
Bungkus coroutine dalam sebuah Tugas - adalah cara untuk memulai coroutine ini "di latar belakang". Berikut contohnya:
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())
Keluaran:
first
long_operation started
second
long_operation finished
Anda bisa menggantinya asyncio.ensure_future(long_operation())
dengan hanya await long_operation()
merasakan perbedaannya.
create_task
jika Anda benar-benar membutuhkan objek tugas, yang biasanya tidak Anda perlukan: github.com/python/asyncio/issues/477#issuecomment-268709555ensure_future
secara otomatis menambahkan dibuatTask
ke loop acara utama?loop
argumen kata kunci ( lihat tanda tangan ensure_future ).await
dalammsg()
untuk kembali kontrol ke acara loop pada panggilan kedua. Perulangan peristiwa setelah menerima kontrol akan dapat dimulailong_operation()
. Itu dibuat untuk menunjukkan bagaimanaensure_future
memulai coroutine untuk mengeksekusi secara bersamaan dengan aliran eksekusi saat ini.create_task()
ensure_future()
create_task
,Seperti yang Anda lihat, create_task lebih spesifik.
async
berfungsi tanpa create_task atau sure_futureasync
Fungsi pemanggilan sederhana mengembalikan coroutineDan karena
gather
under the hood memastikan (ensure_future
) bahwa arg adalah futures, secara eksplisitensure_future
menjadi mubazir.Pertanyaan serupa Apa perbedaan antara loop.create_task, asyncio.async / sure_future dan Task?
sumber
Dari dokumen resmi:
Detil:
Jadi sekarang, di Python 3.7 dan seterusnya, ada 2 fungsi pembungkus tingkat atas (serupa tetapi berbeda):
asyncio.create_task
: yangevent_loop.create_task(coro)
langsung menelepon . ( lihat kode sumber )ensure_future
yang juga memanggilevent_loop.create_task(coro)
jika itu coroutine atau hanya untuk memastikan tipe yang dikembalikan menjadi asyncio.Future . ( lihat kode sumber ). Bagaimanapun,Task
masih merupakanFuture
warisan kelasnya ( ref ).Nah, sebenarnya kedua fungsi pembungkus ini akan membantu Anda menelepon
BaseEventLoop.create_task
. Satu-satunya perbedaan adalahensure_future
menerimaawaitable
objek apa pun dan membantu Anda mengubahnya menjadi Masa Depan. Dan juga Anda dapat memberikanevent_loop
parameter Anda sendiri diensure_future
. Dan tergantung apakah Anda membutuhkan kemampuan itu atau tidak, Anda dapat memilih pembungkus mana yang akan digunakan.sumber
untuk contoh Anda, ketiga jenis tersebut dijalankan secara asinkron. satu-satunya perbedaan adalah, pada contoh ketiga, Anda membuat 10 coroutine sebelumnya, dan dikirimkan ke loop bersama-sama. jadi hanya yang terakhir yang memberikan keluaran secara acak.
sumber