Summary: in this tutorial, you’ll learn about Python asyncio
future objects and understand how they work.
Introduction to the Python asyncio future
A future is an object that returns a value later in the future but not now. Typically, a future object is the result of an asynchronous operation.
For example, you may call an API from a remote server and expect to receive the result later. The API call may return a future object so that you can await it.
To create a future object, you use the Future
class from the asyncio
package. Consider the following example:
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())
Code language: Python (python)
How it works.
First, import Future
class from the asyncio
library:
from asyncio import Future
Code language: Python (python)
Next, create a new Future
object in the main()
coroutine:
my_future = Future()
Code language: Python (python)
A newly created future doesn’t have any value because it doesn’t exist yet. In this state, the future is considered incomplete, unresolved, or not done.
Then, call the done()
method to check the status of the future object:
print(my_future.done()) # False
Code language: Python (python)
It returns False
.
After that, set a value for the future object by calling the set_result()
method:
my_future.set_result('Bright')
Code language: Python (python)
Once you set the value, the future is done. Calling the done()
method of the future object in this stage returns True
:
print(my_future.done()) # True
Code language: Python (python)
Finally, get the result from the future object by calling its result()
method:
print(my_future.result())
Code language: Python (python)
Using Python asyncio future with await
When you use the await
keyword with a future, you pause the future until it returns a value. The following example shows how to use the future with await
keyword:
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())
Code language: Python (python)
Output:
Planning my future... Bright
Code language: Python (python)
How it works.
First, define a coroutine that accepts a future and sets its value after 1 second:
async def plan(my_future: Future): print('Planning my future...') await asyncio.sleep(1) my_future.set_result('Bright')
Code language: Python (python)
Second, define a create()
function that schedules the plan()
coroutine as a task and returns a future object:
def create() -> Future: my_future = Future() asyncio.create_task(plan(my_future)) return my_future
Code language: Python (python)
Third, call the create()
function that returns a future, use the await keyword to wait for the future to return a result, and display it:
async def main(): my_future = create() result = await my_future print(result)
Code language: Python (python)
In practice, you’ll rarely need to create Future
objects directly. However, you’ll use the Future
objects returned from API. Therefore, it’s important to understand how the Future
works.
Futures, Tasks, and Coroutines
The following class hierarchy shows the relationships between Coroutine, Future, and Task:
In this class hierarchy, Courtine, Future, and Task are subclasses of the Awaitable abstract class.
The Awaitable
class has an abstract method __await__()
. Any class that has the implementation of the __await__()
method can be used with the await keyword. And the objects of classes that can be used with the await
keyword are called awaitables.
Leave a Reply