Define
def creates a function: a named list of steps. Python stores it under the name area, for later. The indented line does not run yet. w and h are parameters: names for values a caller will hand in.
First call
Line 4 calls area with the arguments 3 and 4. Python pauses line 4, remembers where it was, and jumps to the top of area. A new call frame appears: scratch space for this one call.
The arguments are matched to the parameters in order: w = 3 and h = 4. These names live in the call frame. They are local variables: they exist only inside this call.
Line 2 works out w * h: 3 * 4 is 12. return ends the call and sends 12 back to line 4, exactly where the call was made. The call is over, so its frame is cleared away.
Line 4 carries on from where it paused. area(3, 4) has become the value 12, so a = 12 stores it. The local names w and h are gone: print(w) here would stop with a NameError.
Second call
Line 5 calls area again, with 5 and 2. The highlight jumps into the same two lines. A brand-new frame appears with w = 5 and h = 2; nothing is left over from the first call.
Line 2 runs again with the new values: 5 * 2 is 10. return sends 10 back to line 5, the line that made this call, and this frame is cleared away too.
Line 5 finishes: b = 10. The function behaved like a small machine. Values went in as arguments, one value came out with return, and its scratch space vanished afterwards.
Why functions
Line 6 works out a + b, which is 12 + 10 = 22, and print shows it on the screen. print is a function too, one Python already provides. You call it the same way.
Two answers, but the steps were written once. Without a function you would type w * h at every place you need it. With one, a change inside area fixes every call at once.
Try it in the Python prompt
;; step 1/10 · line 1: def area(w, h): >>> def area(w, h): ... return w * h ... >>> area <function area at 0x…>
The drawing shows each call’s local variables on a tray, the call frame. In CPython every call gets its own frame object; when the call returns, the frame is released and its local names can no longer be reached. A function that ends without a return statement sends back the special value None.