![]()
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
tryblock executes the division operation. - Since there is no error (no
ZeroDivisionError), the code inside theelseblock runs, printing the result. - If there had been an error, the
elseblock 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
tryblock attempts to open and read from a file. - If the file is not found, the
exceptblock is executed, printing an error message. - Regardless of whether an error occurred or not, the
finallyblock 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
tryblock attempts to divide the numbers. - The
elseblock runs because no exception occurs, printing the division result. - The
finallyblock runs after theelseblock, regardless of whether an exception occurred or not, ensuring cleanup actions are performed.
4. Key Points to Remember
When to Use else:
- Use the
elseblock 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
tryblock is successful, such as logging success, or performing additional tasks that are contingent on no errors.
When to Use finally:
- Use the
finallyblock to ensure that specific code runs regardless of what happens in thetryandexceptblocks. - 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:
try: The code that might raise an exception is placed here.except: If an exception is raised, the code in this block is executed.else: If no exception occurs in thetryblock, this block is executed.finally: This block always executes after thetry(and optionally afterexceptorelse).
Important:
- If the
tryblock executes without errors, theexceptblock is skipped, theelseblock executes, and then thefinallyblock runs. - If an exception occurs, the
exceptblock handles the error, theelseblock is skipped, and thefinallyblock executes. - The
finallyblock 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 theelseblock runs and prints the result, followed by thefinallyblock. - In the second call (
divide_numbers(10, 0)), aZeroDivisionErroroccurs, so theexceptblock handles the error, and thefinallyblock executes afterward.
