大多數的工做只涉及到Task、create_task()方法,就像前面代碼同樣,Future是Task的父類,提供與loop交互的全部功能。bash
Future對象表示某個活動的將來完成狀態,由loop管理,Task與之徹底相同,但其活動特指coroutine。Future表示與loop交互的狀態,Future對象描述的是完成狀態的切換,其實例建立時狀態是「還沒有完成」,而後在稍後的一段時間後,實例狀態爲完成,Future的實例有一個done()
方法用於檢查狀態。框架
>>> from asyncio import Future >>> f = Future() >>> f.done() False
Future實例可能:async
set_result(value)
、result()
);cancel()
取消(經過cancelled()
檢查);即便Task更廣泛,但Future仍然沒法避免,例如在executor中運行一個函數會返回一個Future對象而非Task。函數
>>> async def main(f: asyncio.Future): # 1 ... await asyncio.sleep(1) ... f.set_result('I have finished') # 2 >>> loop = asyncio.get_event_loop() >>> fut = asyncio.Future() # 3 >>> print(fut.done()) # 4 False >>> loop.create_task(main(fut)) # 5 <Task pending coro=<main() running at <stdin>:1>> >>> loop.run_until_complete(fut) # 6 'I have finished' >>> print(fut.done()) True >>> print(fut.result()) # 7 I have finished
絕大多數代碼都不會像上面同樣直接用Future對象,這裏僅做學習用。oop
create_task
仍是ensure_future
?後者很容易形成誤解,從官方的函數docstring看:學習
asyncio.ensure_future(coro_or_future, *, loop=None)
Schedule the execution of a coroutine object: wrap it in a future. Return a Task object.
If the argument is a Future, it is returned directly.code
清楚的解釋一下:
1. 若是傳入一個coroutine,它將返回一個Task(coroutine將會在loop中調度),這與直接調用create_task()沒區別;
2. 若是傳入一個Future,直接返回,徹底沒有改變地!對象
import asyncio async def f(): # 1 pass coro = f() # 2 loop = asyncio.get_event_loop() # 3 task = loop.create_task(coro) # 4 assert isinstance(task, asyncio.Task) # 5 new_task = asyncio.ensure_future(coro) # 6 assert isinstance(new_task, asyncio.Task) mystery_meat = asyncio.ensure_future(task) # 7 assert mystery_meat is task # 8
實際上,ensure_future()
是提供給框架開發者處理兩種參數用的。ci
在3.7中,asyncio提供了asyncio.create_task(coro)
方法來爲運行中的loop添加task,ensure_future()
能夠失業了。開發