Using finally and else in Exception Handling

Loading

In Python, exception handling is done using try, except, else, and finally blocks. While most of the focus tends to be on try and except, the else and finally blocks add additional control and flexibility to exception handling. These blocks help in managing the flow of code after exceptions are caught or avoided, and they ensure that necessary cleanup is always performed.


1. The else Block in Exception Handling

The else block is an optional part of exception handling that is executed if the try block does not raise an exception. This is particularly useful when you want to separate the code that runs when there are no errors from the error-handling code. The code inside the else block only runs if no exception is raised within the try block.

Syntax:

try:
# Code that may raise an exception
risky_code()
except SomeException:
# Code to handle the exception
handle_error()
else:
# Code that runs only if no exception occurs
code_if_no_error()

Example: Using else in Exception Handling

try:
x = 10 / 2 # This will work fine
except ZeroDivisionError:
print("Cannot divide by zero!")
else:
print(f"Division successful! The result is {x}")

Output:

Division successful! The result is 5.0

Explanation:

  • The try block executes the division operation.
  • Since there is no error (no ZeroDivisionError), the code inside the else block runs, printing the result.
  • If there had been an error, the else block would have been skipped.

2. The finally Block in Exception Handling

The finally block is also optional but is used to define code that should always execute, regardless of whether an exception was raised or not. This is especially useful for cleanup tasks such as closing files, releasing resources, or performing actions that must occur after the try block, no matter what.

Even if an exception is raised and caught, or if the program exits the try block normally, the code inside finally will run.

Syntax:

try:
# Code that may raise an exception
risky_code()
except SomeException:
# Code to handle the exception
handle_error()
finally:
# Code that always runs, regardless of exception occurrence
cleanup_code()

Example: Using finally for Cleanup

try:
file = open("example.txt", "r") # Try to open a file
content = file.read() # Read file content
except FileNotFoundError:
print("File not found!")
finally:
if 'file' in locals():
file.close() # Close the file, whether an error occurred or not
print("File has been closed.")

Output:

File not found!
File has been closed.

Explanation:

  • The try block attempts to open and read from a file.
  • If the file is not found, the except block is executed, printing an error message.
  • Regardless of whether an error occurred or not, the finally block is executed, ensuring that the file is closed if it was successfully opened.

3. Using else and finally Together

You can combine both else and finally blocks in a try-except statement. While else handles the situation when no exceptions are raised, finally ensures that certain actions (like cleanup) always occur, no matter what.

Syntax:

try:
# Code that may raise an exception
risky_code()
except SomeException:
# Code to handle the exception
handle_error()
else:
# Code that runs only if no exception occurs
code_if_no_error()
finally:
# Code that always runs, regardless of exception occurrence
cleanup_code()

Example: Using else and finally Together

try:
result = 10 / 2 # This will succeed
except ZeroDivisionError:
print("Cannot divide by zero!")
else:
print(f"Division successful! The result is {result}")
finally:
print("Cleaning up resources...")

Output:

Division successful! The result is 5.0
Cleaning up resources...

Explanation:

  • The try block attempts to divide the numbers.
  • The else block runs because no exception occurs, printing the division result.
  • The finally block runs after the else block, regardless of whether an exception occurred or not, ensuring cleanup actions are performed.

4. Key Points to Remember

When to Use else:

  • Use the else block when you want to separate the normal execution flow (the code that should run if no exceptions occur) from the exception handling logic.
  • It’s helpful for code that should only run if the try block is successful, such as logging success, or performing additional tasks that are contingent on no errors.

When to Use finally:

  • Use the finally block to ensure that specific code runs regardless of what happens in the try and except blocks.
  • This is typically used for cleanup actions like closing files, releasing network resources, or other essential tasks that must happen whether or not an error occurred.

Order of Execution:

  1. try: The code that might raise an exception is placed here.
  2. except: If an exception is raised, the code in this block is executed.
  3. else: If no exception occurs in the try block, this block is executed.
  4. finally: This block always executes after the try (and optionally after except or else).

Important:

  • If the try block executes without errors, the except block is skipped, the else block executes, and then the finally block runs.
  • If an exception occurs, the except block handles the error, the else block is skipped, and the finally block executes.
  • The finally block executes whether an exception is raised or not.

5. Example: Putting it All Together

def divide_numbers(a, b):
try:
result = a / b
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
else:
print(f"Result: {result}")
finally:
print("Execution complete, cleaning up resources...")

divide_numbers(10, 2)
divide_numbers(10, 0)

Output:

Result: 5.0
Execution complete, cleaning up resources...
Error: Cannot divide by zero.
Execution complete, cleaning up resources...

Explanation:

  • In the first call (divide_numbers(10, 2)), there is no exception, so the else block runs and prints the result, followed by the finally block.
  • In the second call (divide_numbers(10, 0)), a ZeroDivisionError occurs, so the except block handles the error, and the finally block executes afterward.

Leave a Reply

Your email address will not be published. Required fields are marked *