定义: Future的本质是一个占位符对象,表示一个尚未完成的异步操作的结果。它允许您在异步操作完成后获取其结果或处理错误。
Future的状态: 其具有不同的状态
通常包括以下几种状态:
Pending(未完成): 初始状态,表示异步操作尚未完成。
Running(运行中): 表示异步操作正在执行。
Cancelled(已取消): 表示异步操作被取消,通常是由于超时或其他原因。
Finished(已完成): 表示异步操作已成功完成,具有一个结果值。
Errored(出错): 表示异步操作完成时出现错误。
创建: 通常通过asyncio.Future()
或其他异步框架提供的类似方式来创建Future
对象。
结构:
asyncio.isfuture(obj)
参数:
obj: 要检查的对象。
作用:
用于检查给定的对象是否是 asyncio
模块中的 asyncio.Future
或其子类的实例。如果是 asyncio.Future
的实例或其子类,该函数将返回 True
,否则返回 False
。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
async def main():
future = asyncio.create_task(my_coroutine())
print(asyncio.isfuture(future)) # 输出 True
print(asyncio.isfuture("Hello")) # 输出 False
if __name__ == "__main__":
asyncio.run(main())
结构:
asyncio.ensure_future(coro, *, loop=None)
参数:
coro: 要包装成 Task
对象的协程函数(或可等待对象)。
loop: 可选参数,指定要使用的事件循环。如果不提供 loop
参数,则会使用当前默认的事件循环。
作用:
用于创建一个 Task
对象,表示一个异步任务。它的作用类似于 asyncio.create_task()
,用于将协程函数包装成一个 Task
对象,以便能够在事件循环中调度执行。
注意:
asyncio.ensure_future()
返回一个Task
对象,该对象表示了要执行的异步任务。与asyncio.create_task()
不同,asyncio.ensure_future()
不会直接将任务添加到事件循环中,而是返回一个任务对象,您需要稍后手动添加到事件循环中,或者在await
该任务时自动将其添加到事件循环中。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
async def main():
# 使用 asyncio.ensure_future() 创建一个 Task 对象
task = asyncio.ensure_future(my_coroutine())
# 将任务添加到事件循环中
result = await task
print(result) # 输出 "Hello, World!"
if __name__ == "__main__":
asyncio.run(main())
结构:
asyncio.wrap_future(future, loop=None)
参数:
future: 要包装的非异步 Future
对象。
loop: 可选参数,指定要使用的事件循环。如果不提供 loop
参数,则会使用当前默认的事件循环。
作用:
用于将一个非异步的 concurrent.futures.Future
或其他类似的 Future
对象包装成 asyncio.Future
对象,以便在 asyncio
中使用。这个函数通常用于将标准的concurrent.futures
模块中的Future
对象转换为asyncio
模块中的Future
对象,从而实现异步和协程的兼容性。
注意:
asyncio.wrap_future()
返回一个asyncio.Future
对象,该对象表示了原始的非异步Future
对象。这样,您可以在asyncio
中使用非异步Future
对象,并将其与协程和异步操作一起工作。
import asyncio
import concurrent.futures
def blocking_function():
import time
time.sleep(2)
return "Hello, World!"
async def main():
# 创建一个 concurrent.futures.Future 对象
executor = concurrent.futures.ThreadPoolExecutor()
future = executor.submit(blocking_function)
# 使用 asyncio.wrap_future() 包装成 asyncio.Future 对象
asyncio_future = asyncio.wrap_future(future)
# 等待 asyncio.Future 完成
result = await asyncio_future
print(result) # 输出 "Hello, World!"
if __name__ == "__main__":
asyncio.run(main())
在这个示例中,我们首先创建了一个标准库 concurrent.futures.ThreadPoolExecutor
对象,然后使用 executor.submit()
启动一个阻塞函数 blocking_function()
。接下来,我们使用 asyncio.wrap_future()
将 concurrent.futures.Future
包装成 asyncio.Future
,并在协程中等待其完成。这样,我们就能够在 asyncio
中与标准库中的 Future
对象一起使用。
结构:
result = future.result()
作用:
该方法用于获取 asyncio.Future
或 concurrent.futures.Future
对象的结果值的常用方法。
这个方法的行为会根据 Future
对象的状态进行不同的处理:
如果 Future
对象已经成功完成(状态为 Finished
),result()
方法将返回异步操作的结果值。
如果 Future
对象尚未完成(状态为 Pending
或 Running
),result()
方法将阻塞当前协程或线程,等待操作完成,并返回结果值。
如果 Future
对象表示的操作出现错误(状态为 Errored
),result()
方法将引发相应的异常,通常是 asyncio.CancelledError
或其他异常,以指示操作失败。
注意
在使用
result()
方法时,特别是在异步程序中,应该小心处理可能的异常,以避免程序中断。通常,最好使用try
/except
块来捕获和处理异常,以确保程序的稳定性。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_result(task.result())
)
try:
# 等待 asyncio.Future 完成并获取结果
result = future.result()
print(result) # 输出 "Hello, World!"
except asyncio.CancelledError:
print("The task was cancelled.")
except Exception as e:
print("An error occurred:", e)
if __name__ == "__main__":
asyncio.run(main())
结构:
future.set_result(result)
参数:
result: 要设置的异步操作的结果值
作用:
用于将结果值设置到 asyncio.Future
对象中的方法。asyncio.Future
是用于表示异步操作结果的对象,通过 set_result()
方法,您可以将异步操作的结果设置为成功完成,并将结果值存储在 Future
对象中。
注意:
使用
set_result()
方法时,通常应该确保操作已成功完成,因为这个方法会将Future
对象的状态从未完成(Pending
)更改为已完成(Finished
),并存储结果值。如果操作未完成或出现错误,可能会引发异常。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_result(task.result())
)
# 等待 asyncio.Future 完成
result = await future
print(result) # 输出 "Hello, World!"
if __name__ == "__main__":
asyncio.run(main())
结构:
future.set_exception(exception)
参数:
exception: 要设置的异常对象,通常是一个 Exception 子类的实例,用于表示操作的错误原因。
作用:
用于将异常设置到 asyncio.Future
对象中的方法。asyncio.Future
通常用于表示异步操作的结果,而 set_exception()
方法允许您将异常信息与该结果关联起来,以表示异步操作的错误状态。
注意:
使用
set_exception()
方法时,通常应确保操作已出错,因为这个方法会将Future
对象的状态从未完成(Pending
)更改为已完成(Errored
),并存储异常对象。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
raise ValueError("An error occurred")
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作,此处故意引发异常
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_exception(task.exception())
)
try:
# 等待 asyncio.Future 完成
await future
except asyncio.CancelledError:
print("The task was cancelled.")
except Exception as e:
print("An error occurred:", e) # 输出 "An error occurred: An error occurred"
if __name__ == "__main__":
asyncio.run(main())
结构:
done = future.done()
作用:
用于检查异步操作是否已经完成。asyncio.Future
通常用于表示异步操作的结果,而 done()
方法用于查询操作的状态。
如果 Future
对象已经成功完成(状态为 Finished
),则返回 True
。
如果 Future
对象尚未完成(状态为 Pending
或 Running
),则返回 False
。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_result(task.result())
)
# 检查 asyncio.Future 是否已完成
if not future.done():
print("Future is not yet done.")
else:
result = future.result()
print("Future result:", result) # 输出 "Future result: Hello, World!"
if __name__ == "__main__":
asyncio.run(main())
结构:
cancelled = future.cancelled()
作用:
用于检查异步操作是否已被取消。asyncio.Future
通常用于表示异步操作的结果,而 cancelled()
方法用于查询操作是否被取消。
如果 Future
对象已被取消,返回 True
。
如果 Future
对象尚未被取消或已经完成,返回 False
通常,在协程或异步任务中,您可以使用 cancelled()
方法来检查操作是否被取消,并根据需要采取相应的操作。如果操作被取消,您可以处理取消的情况,例如清理资源或执行其他必要的操作。
import asyncio
async def my_coroutine():
try:
await asyncio.sleep(1)
except asyncio.CancelledError:
print("Coroutine was cancelled")
async def main():
task = asyncio.create_task(my_coroutine())
await asyncio.sleep(0.5) # 在0.5秒后取消任务
task.cancel()
if task.cancelled():
print("Task was cancelled")
else:
print("Task was not cancelled")
if __name__ == "__main__":
asyncio.run(main())
结构:
future.add_done_callback(callback)
参数:
callback: 要添加的回调函数,通常是一个接受一个参数的可调用对象,该参数是 Future
对象本身。
作用:
用于添加一个回调函数,该回调函数会在 Future
对象完成(成功或出错)时被调用。回调函数会接收一个参数,即 Future
对象本身,允许您在异步操作完成后执行特定的操作或处理结果。
add_done_callback()
方法允许您注册一个回调函数,以便在 Future
对象的状态发生变化时执行特定的操作。这在异步编程中很有用,可以用于处理操作完成后的清理、通知或其他异步操作。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
def callback(future):
if future.cancelled():
print("Future was cancelled")
elif future.done() and not future.cancelled():
result = future.result()
print("Future result:", result)
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 添加回调函数
future.add_done_callback(callback)
# 启动异步操作
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_result(task.result())
)
try:
# 等待 asyncio.Future 完成
await future
except asyncio.CancelledError:
print("Future was cancelled")
if __name__ == "__main__":
asyncio.run(main())
结构:
future.cancel()
作用:
用于取消异步操作,即将与 Future
关联的协程或任务标记为取消状态。这个方法允许您在某些情况下停止异步操作的执行。
当调用 cancel()
方法时,会发生以下情况:
如果 Future
对象尚未完成(状态为 Pending
或 Running
),则将其状态更改为已取消(Cancelled
)。
如果 Future
对象已经完成(状态为 Finished
或 Errored
),则取消操作不会生效,因为已经完成的操作无法取消。
一旦异步操作被取消,协程或任务会在适当的时候引发 asyncio.CancelledError
异常,以通知操作已被取消。您可以在协程内部捕获这个异常并执行适当的处理。
import asyncio
async def my_coroutine():
try:
await asyncio.sleep(1)
print("Coroutine completed")
except asyncio.CancelledError:
print("Coroutine was cancelled")
async def main():
# 启动异步操作
task = asyncio.create_task(my_coroutine())
await asyncio.sleep(0.4)
task.cancel()
# 去报任务被取消
if task.cancelled():
print("task was cancelled")
else:
print("task was not cancelled")
if __name__ == "__main__":
asyncio.run(main())
结构:
exc = future.exception()
作用:
用于获取异步操作引发的异常。asyncio.Future
通常用于表示异步操作的结果,如果操作失败或出现异常,可以使用 exception()
方法获取异常信息。
exception()
方法返回一个异常对象:
如果 Future
对象尚未完成或成功完成(状态为 Pending
、Running
或 Finished
),或者未引发异常,则返回 None
。
如果 Future
对象已完成且引发了异常(状态为 Errored
),则返回引发的异常对象。
通常,您可以使用 exception()
方法来检查异步操作是否引发了异常,并根据需要处理异常情况。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
raise ValueError("An error occurred")
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作,此处故意引发异常
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_exception(task.exception())
)
try:
# 等待 asyncio.Future 完成
await future
except asyncio.CancelledError:
print("Future was cancelled")
except Exception as e:
print("An error occurred:", e) # 输出 "An error occurred: An error occurred"
# 获取并输出异常信息
exception = future.exception()
if exception is not None:
print("Exception:", exception) # 输出 "Exception: An error occurred"
if __name__ == "__main__":
asyncio.run(main())
结构:
loop = future.get_loop()
作用:
用于获取与该 Future
关联的事件循环(event loop)。这个方法返回与 Future
对象相关联的事件循环对象,如果未关联任何事件循环,则返回 None
。
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
async def main():
# 创建一个 asyncio.Future 对象
future = asyncio.Future()
# 启动异步操作
asyncio.create_task(my_coroutine()).add_done_callback(
lambda task: future.set_result(task.result())
)
try:
# 等待 asyncio.Future 完成
await future
except asyncio.CancelledError:
print("Future was cancelled")
# 获取并输出与 Future 关联的事件循环
future_loop = future.get_loop()
if future_loop is not None:
print("Future is associated with the event loop.")
else:
print("Future is not associated with any event loop.")
if __name__ == "__main__":
asyncio.run(main())