async/await Syntax — Junior¶
At junior level, focus on this question:
What does an
async fn's return type actually become, under the hood?
async fn returns a future/coroutine object, not the value directly¶
async def get_user(user_id):
return {"id": user_id, "name": "Alice"}
result = get_user(42)
print(type(result)) # <class 'coroutine'> - NOT a dict!
print(result) # <coroutine object get_user at 0x...>
Calling an async def function doesn't run its body at all yet — it immediately returns a coroutine object (per the Coroutines & Generators junior page's generator analogy). You must await it (or otherwise drive it, per Futures/Promises/Tasks) to actually get the underlying value:
async def caller():
result = await get_user(42) # NOW actually runs, gets the real dict
print(result) # {"id": 42, "name": "Alice"}
🎓 Takeaway:
asyncfundamentally changes a function's type signature — a function that logically returnsdictactually returns "a coroutine/future that will eventually produce adict." This type change is exactly why you cannot use anasync fn's result directly withoutawaiting it first, and it's the root cause ofmiddle.md's function-coloring propagation.
Test yourself¶
- Why does calling an
async deffunction not execute its body immediately? - What is the actual runtime type of the value returned by calling an
async deffunction, before it's awaited? - What would happen if you tried to use
get_user(42)'s result directly (withoutawait) as if it were the dict itself?
Continue to middle.md.