What can go wrong
Some mistakes only show up while a program runs, such as dividing by zero. Python then raises an exception: an object that names what went wrong. If nothing catches it, the program stops.
Lines 1 and 2 define share(), which splits a total between people. def only stores the function under its name; the body on line 2 runs later, each time share() is called.
Line 3, try:, starts a guarded block: the indented line 4 under it. Python runs it as usual, but if it raises an exception, Python jumps to the except clauses below instead of stopping.
Raised and caught
Line 4 calls share(12, 0). Python makes a frame, a small workspace for this one call, holding total = 12 and people = 0, and stacks it on the module's frame. Line 4 waits for the answer.
Line 2 works out 12 / 0. Dividing by zero has no answer, so Python abandons the line and raises an exception: a ZeroDivisionError object carrying the message division by zero.
share() has no try of its own, so the exception leaves it. The frame is thrown away, unfinished, and the exception arrives back at line 4. The assignment never happens: each is never set.
Line 4 is inside try, so Python checks the except clauses in order. except ZeroDivisionError matches the exception's type, so it is caught. as err gives the exception object a name.
Line 6 runs instead of the rest of the try block. print() writes Oops: and then err, which prints as its message: division by zero. The exception is handled, so it is finished.
After the except block, the program carries on with line 7 and prints Done. Because the exception was caught, the program reaches its end normally and exits with status 0, meaning success.
Uncaught
Delete try and except and nothing catches the exception. It climbs out of every frame, Python prints a traceback, the trail of calls that led to the error, and stops. Done never prints.
Try it yourself
;; step 1/10
>>> 12 / 0
Traceback (most recent call last):
... # where it happened
ZeroDivisionError: division by zero
>>> int("ten") # another kind of exception
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: 'ten'
On macOS and Linux the command is often python3 rather than python; on Windows the py launcher also works. The $ is the terminal's own prompt: you do not type it. The figure shortens the traceback. The real one lists each call, oldest first and newest last, with its file, line number and source line, then the exception type and message. In the real message, the ... is the full path to the file.