Welcome! Today, we will manage exceptions within Python functions, much like an astronaut tackling obstacles in space. We will delve into the concept of functions, acquaint ourselves with the handling of exceptions, and investigate their operation during function calls.
Let's take a moment to recap: An exception, an error that can lead to a program crash, can be disruptive. However, a Python function can attempt certain tasks and catch potential exceptions using a try-except-finally block. This is similar to an astronaut preparing for potential hurdles. Below is an illustration:
This function monitors for a ZeroDivisionError when performing division.
The raise keyword in Python triggers an exception manually within a function. Consider a function that calculates a square root — an error should occur if the input is negative!
An exception is raised if a negative input is detected.
The code that calls a function handles any possible exceptions that the function might throw. This is illustrated as follows:
In this scenario, exceptions raised in safe_sqrt are captured in call_sqrt.
Exceptions can migrate from one function to another. In nested calls, a raised exception gets passed up the chain; for instance, if fun2 raises exceptions and the except block does not handle them, they're forwarded to fun1.
In this scenario, fun1() might throw ExceptionType if it occurs, as it's not handled by the except block.
