This chapter covers the philosophy of error handling, Python's exception hierarchy, the try-except-else-finally syntax, and context managers.
- Stack Unwinding: The process of searching for an exception handler by going up the call stack.
- Exception Safety Levels:
- Nothrow: The function is guaranteed not to throw exceptions.
- Strong: If an exception is thrown, the program state remains unchanged (rollback).
- Basic: If an exception is thrown, no resources are leaked and the state remains valid (though possibly changed).
- Strategy: Handle exceptions as close to the source as possible, or at clear "boundaries" (user input, thread, process).
- Syntax:
try: # Code that might raise an exception except ValueError as e: # Handle specific exception except (TypeError, KeyError): # Handle multiple exceptions else: # Run if NO exception was raised finally: # ALWAYS run (cleanup)
- Raising: Use
raiseto trigger an exception, or a bareraiseinside anexceptblock to re-raise the current exception. - Chaining: Use
raise NewException from old_exceptionto preserve context via the__context__and__cause__attributes.
Define your own exceptions by inheriting from the built-in Exception class. It's a best practice to create a base Error class for your module/library.
Context managers ensure resources (like files or database connections) are properly cleaned up.
- Protocol: Implement
__enter__(setup) and__exit__(teardown). contextlib:@contextmanager: Create a context manager using a generator.suppress(*exceptions): Ignore specific exceptions.ContextDecorator: Allow a context manager to also be used as a decorator.
01-theory.py: Philosophy, stack unwinding, andtry-finallyvstry-except.02-python.py: Common built-in exceptions andtry-except-else-finallyblocks.03-exception-api.py: Chaining,__context__, and__traceback__.04-multiple.py: Handling multiple exceptions and custom exception hierarchies.05-with.py: Deep dive into__enter__/__exit__andcontextlibutilities.06-pdb.py: Interactive debugging withpdb.set_trace().