Lesson 34 of 35Python
Python · Lesson 34 · 30 minutes
async and await
What you'll learn
- Understand what “waiting at the same time” means
- Work with
asyncdef,awaitandasyncio.run - Run several tasks in parallel with
asyncio.gather
Waiting without standing around
Imagine you’re cooking pasta and baking a pizza at the same time. You don’t stand in front of the pot for 10 minutes and then in front of the oven for 15 – you start both and do something else until one is ready. That’s exactly what asynchronous programming is.
Good to know: Codelix runs a learning version of
asynciowith a simulated clock: the order is the same as in real Python, but you don’t actually have to wait.asyncio.zeit()shows you the simulated time – this function only exists here (“zeit” is German for time).
async def and await
A function with async def is a coroutine. With await it waits for something without blocking the whole program. Everything is started with asyncio.run():
import asyncio
async def cook(dish, minutes):
print(f"{dish} starts")
await asyncio.sleep(minutes)
print(f"{dish} ready after {minutes} minutes")
async def main():
await cook("Pasta", 10)
await cook("Pizza", 15)
print("Total time:", asyncio.zeit())
asyncio.run(main())Here everything is still cooked one after the other: 25 minutes.
At the same time with gather
asyncio.gather() starts several coroutines at once and waits until all of them are finished:
import asyncio
async def cook(dish, minutes):
print(f"{dish} starts")
await asyncio.sleep(minutes)
print(f"{dish} ready")
return dish
async def main():
results = await asyncio.gather(cook("Pasta", 10), cook("Pizza", 15))
print(results)
print("Total time:", asyncio.zeit())
asyncio.run(main())Now everything only takes as long as the longest dish: 15 minutes.
Remember:
asyncis worth it when a program does a lot of waiting – for the internet, for files or for a robot sensor. It doesn’t make calculations faster.
Quick check
Before you start the task: what does this program print? Type your guess – then Python works it out.
import asyncio
async def say(text, delay):
await asyncio.sleep(delay)
print(text)
async def main():
await asyncio.gather(say("A", 0.2), say("B", 0.1))
asyncio.run(main())Your task
Your turn
A robot should do three things at the same time: start the motor (2 seconds), calibrate the sensor (1 second) and run a light test (3 seconds). Let all three run in parallel with asyncio.gather. Afterwards asyncio.zeit() should give 3.0 – not 6.0 like one after another.
import asyncio
async def task(name, seconds):
await asyncio.sleep(seconds)
print(f"{name} done")
async def main():
# start all three at the same time
await task("Motor", 2)
await task("Sensor", 1)
await task("Light", 3)
print("Total time:", asyncio.zeit())
asyncio.run(main())- Something to think about
Replace the three
awaitlines with oneawaitasyncio.gather(task(...), task(...), task(...)). - Gap code – fill in the ___
import asyncio async def task(name, seconds): await asyncio.sleep(seconds) print(f"{name} done") async def main(): # start all three at the same time ___ ___ ___ ___ ___ print("Total time:", asyncio.zeit()) asyncio.run(main())
Solve it without hints to earn a ⭐ on your progress page.
Show solution🔒 Unlocks after all hints or 2 checks
Try it yourself first – mistakes teach you the most. Here is one possible solution:
import asyncio
async def task(name, seconds):
await asyncio.sleep(seconds)
print(f"{name} done")
async def main():
# start all three at the same time
await asyncio.gather(
task("Motor", 2),
task("Sensor", 1),
task("Light", 3),
)
print("Total time:", asyncio.zeit())
asyncio.run(main())