When it comes to programming styles, we often contrast pessimists and optimists. Optimists believe that potential errors in program behavior can be avoided by carefully checking preconditions (see ).
Don’t divide by zero! (Check the divisor.)
Don’t read a nonexistent file! (Check if the file exists.)
Don’t access the 10th character in a 5-character string! (Check the string length.)
Don’t append to a tuple! (Check if the target is mutable.)
This strategy generally works—until the preconditions become too expensive or impossible to verify. That’s when the pessimists step in. They assume that errors are inevitable, so let them happen and deal with them afterward.
Fortunately, violations of preconditions are exceptional situations. When one rarely occurs, Python raises an exception: it alerts the program to the specific problem and invokes a special block of code known as an exception handler, designed to keep the situation under control.
Handling exceptions is essential for writing robust programs that don’t crash unexpectedly and can gracefully handle real-world input and edge cases. Let’s take a closer look at how Python manages exceptions.