Step 1 of 7 · Reading · ~4 min
Learn
Error Handling
Try and Except
You have already met the crashes: int("abc") is a ValueError, a missing dict key is a KeyError, a bad list index is an IndexError. This lesson is how to keep the program running through them, and how to read input when you do not know how many lines are coming.
What runs, and when
except runs only if the try body raised a matching error, and the rest of the body is abandoned at the line that raised. else runs only if the body finished without raising. finally runs every time, including when the body exits through return, break or continue:
The finally line prints before the caller prints the returned value. Put code in else rather than at the end of try when an error in that code should not be caught by your except.
Which errors an except matches
An except matches the named class and every subclass of it. KeyError and IndexError share the parent LookupError, ZeroDivisionError sits under ArithmeticError, and nearly everything sits under Exception. A tuple names several classes at once.
as e binds the exception object, and type(e).__name__ is its class name. str(e) gives the message (division by zero, or 'z' for a KeyError), but that wording belongs to Python and changes between versions, so print the class name when the output must be stable. e is deleted when the except block ends: using it afterwards raises NameError.
Handlers are tried top to bottom and the first match wins. Put the narrow class first:
Broad handlers hide bugs
The bare except swallowed the NameError caused by the typo, and it also catches Ctrl+C. With except ValueError the same program stops and names the typo. Catch the classes you expect, and keep except Exception for a place that records the error.
Python style is EAFP, "easier to ask forgiveness than permission": attempt the operation and handle the failure, as opposed to checking first like in or .get(). It wins when the check is as hard as the job: "-12".isdigit() is False, yet int("-12") works.
Reading until the input ends
input() raises EOFError when no lines are left, which is how a program reads input of unknown length. A last line without a trailing newline is still returned normally.
For the lines 20.5, abc, a blank, 22.5 and 23 this prints 3 readings, 1 rejected.
Common mistakes
- A class missing from the tuple. If
IndexErroris not listed, a line with a missing argument crashes the program with a traceback instead of printing an error line. - Printing
str(e). You geterror division by zerowhereerror ZeroDivisionErrorwas expected. - Counting in the wrong clause. Adding to the success count inside
trybefore the value is checked, or counting blank lines, makes the totals too high. - Treating an unknown value as success. A command the program does not recognise raises nothing, so it reaches
elselooking like a success. Check the value there.
Your exercise
Build a command evaluator that reads until end of input and reports each line. The starter handles reading and blank lines; you supply the try structure and the counting. The likeliest slip is forgetting that a missing argument raises IndexError.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…