1.Event loop and coroutines
The event loop runs one task at a time, switching to another whenever the current one awaits something. A coroutine is a function defined with async def — calling it builds a paused coroutine object, it does not run yet.
Key features
- async def defines a coroutine function; calling it returns a coroutine object immediately
- A coroutine object does nothing until awaited — calling the function alone runs no code
- asyncio.run(main()) creates an event loop, runs main() to completion, then closes the loop
- Only one coroutine runs Python code at a time — the loop is cooperative, not preemptive
- A coroutine created but never awaited triggers a "was never awaited" RuntimeWarning
asyncio — the entry points worth knowing
- main() → greet(): coro = greet("Ada") (builds a coroutine object — nothing runs yet)
- main() → greet(): await coro
- greet() → greet(): await asyncio.sleep(0.05) (loop switches to other work here)
- greet() → main(): return "hello, Ada"
Command
async def fetch(url):
... # a coroutine function
coro = fetch(url) # builds a coroutine object -- nothing has run yet
result = await coro # runs it, suspends the caller until it finishes
asyncio.run(main()) # the only place a loop is created from ordinary codeasync def call() builds a coroutine object that does nothing; await is what actually runs it and gives back the result.