大多数的工做只涉及到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()
能够失业了。开发