摘要:在本教程中,你将学习关于Python异步IO中的Future对象,并了解它们的工作原理。
Python异步IO的Future简介
Future是一个对象,它在未来而不是现在返回一个值。通常情况下,Future对象是异步操作的结果。
例如,你可能会调用远程服务器的API,并期望稍后收到结果。API调用可能返回一个Future对象,这样你就可以等待它。
要创建一个Future对象,你可以使用asyncio包中的Future类。考虑下面的例子:
import asyncio
from asyncio import Future
async def main():
my_future = Future()
print(my_future.done()) # False
my_future.set_result('Bright')
print(my_future.done()) # True
print(my_future.result())
asyncio.run(main())
它是如何工作的。
首先,从asyncio库导入Future类:
from asyncio import Future
接下来,在main()协程中创建一个新的Future对象:
my_future = Future()
新创建的Future对象没有任何值,因为它还不存在。在这个状态下,该Future被认为是不完整的、未解决的或者未完成的。
然后,调用done()方法来检查Future对象的状态:
print(my_future.done()) # False
它返回False。
接着,通过调用set_result()方法为Future对象设置一个值:
my_future.set_result('Bright')
一旦设置了值,该Future就完成了。在这个阶段调用Future对象的done()方法将返回True:
print(my_future.done()) # True
最后,通过调用result()方法从Future对象中获取结果:
print(my_future.result())
使用Python异步IO的Future对象和await关键字
当你在Future对象上使用await关键字时,你会暂停Future,直到它返回一个值。下面的例子展示了如何使用Future和await关键字:
from asyncio import Future
import asyncio
async def plan(my_future):
print('Planning my future...')
await asyncio.sleep(1)
my_future.set_result('Bright')
def create() -> Future:
my_future = Future()
asyncio.create_task(plan(my_future))
return my_future
async def main():
my_future = create()
result = await my_future
print(result)
asyncio.run(main())
输出:
Planning my future...
Bright
它是如何工作的。
首先,定义一个协程,接受一个Future对象,并在1秒后设置它的值:
async def plan(my_future: Future):
print('Planning my future...')
await asyncio.sleep(1)
my_future.set_result('Bright')
然后,定义一个create()函数,将plan()协程作为任务安排,并返回一个Future对象:
def create() -> Future:
my_future = Future()
asyncio.create_task(plan(my_future))
return my_future
接着,调用create()函数返回一个Future,使用await关键字等待Future返回结果,并显示它:
async def main():
my_future = create()
result = await my_future
print(result)
在实践中,你很少需要直接创建Future对象。然而,你会使用从API返回的Future对象。因此,了解Future的工作原理很重要。
Future、Task和协程
以下类层次结构显示了协程(Coroutine)、Future和任务(Task)之间的关系:
在这个类层次结构中,协程(Coroutine)、Future和任务(Task)都是Awaitable抽象类的子类。
Awaitable类有一个抽象方法__await__()。任何实现了__await__()方法的类都可以与await关键字一起使用。可以与await关键字一起使用的类的对象被称为"可等待对象"。
总结
- Future是一个对象,它会在将来而不是现在返回一个值。
- Future、协程(Coroutine)和任务(Task)都是可等待的,它们的对象可以与await关键字一起使用。