Exception handling is a powerful feature in Python that allows you to deal with errors or unexpected conditions in a controlled way, preventing your program from crashing unexpectedly. In Python, you use the try-except
block to catch and handle exceptions (errors) that may occur during the execution of your code.
This technique helps in building robust and fault-tolerant programs, making it easier to diagnose and handle errors, ensuring that the application can continue to run even when something goes wrong.
1. The Basic try-except
Block
The simplest form of exception handling in Python involves wrapping the code that might raise an error in a try
block, and then catching the exception in an except
block. The general structure looks like this:
try:
# Code that may raise an exception
risky_code()
except SomeException:
# Code that runs if an exception occurs
handle_error()
Explanation:
try
: The code inside thetry
block is executed. If an exception occurs during execution, it will immediately jump to theexcept
block.except
: If an exception is raised in thetry
block, it will be caught here, and you can handle the error in a controlled way.
Example: Basic try-except
Handling
try:
x = 1 / 0 # This will raise a ZeroDivisionError
except ZeroDivisionError:
print("Cannot divide by zero!")
Output:
csharpCopyEditCannot divide by zero!
Explanation:
- The
try
block attempts to perform division by zero, which raises aZeroDivisionError
. - The
except
block catches the error and prints a message instead of letting the program crash.
2. Catching Multiple Exceptions
You can handle different types of exceptions using multiple except
blocks. Each block catches a specific type of exception.
Syntax:
try:
# Code that may raise different exceptions
risky_code()
except SomeException:
# Handle SomeException
except AnotherException:
# Handle AnotherException
Example: Catching Multiple Exceptions
try:
x = int("abc") # This will raise a ValueError
except ValueError:
print("Invalid input! Not a valid number.")
except TypeError:
print("There was a type error.")
Output:
Invalid input! Not a valid number.
Explanation:
- The
int("abc")
raises aValueError
because “abc” is not a valid integer. - The
except ValueError
block catches this specific exception and prints an error message.
3. Catching All Exceptions
You can also catch all exceptions using a general except
block. This is useful if you are unsure about the specific exception type, but it should be used carefully because it may catch exceptions that you do not intend to handle.
Syntax:
try:
# Code that may raise any exception
risky_code()
except Exception:
# Catch all exceptions
handle_error()
Example: Catching All Exceptions
try:
result = 10 / 0 # Will raise ZeroDivisionError
except Exception:
print("An error occurred!")
Output:
An error occurred!
Explanation:
- The
except Exception
block will catch any exception that occurs, includingZeroDivisionError
in this case.
4. Handling Exceptions with else
You can use the else
block in exception handling, which will run only if no exception is raised in the try
block. This is useful for code that should only run when the try
block succeeds without errors.
Syntax:
try:
# Code that may raise an exception
risky_code()
except SomeException:
# Handle exception
handle_error()
else:
# Code that runs only if no exception occurs
code_if_no_error()
Example: Using else
try:
result = 10 / 2 # This will work fine
except ZeroDivisionError:
print("Cannot divide by zero!")
else:
print("Division successful, result:", result)
Output:
Division successful, result: 5.0
Explanation:
- The division operation succeeds without errors, so the
else
block runs and prints the result.
5. Using finally
for Cleanup
The finally
block is used for code that must always execute, whether or not an exception was raised. This is useful for cleanup tasks like closing files, releasing resources, or ensuring some important final action happens.
Syntax:
try:
# Code that may raise an exception
risky_code()
except SomeException:
# Handle exception
handle_error()
finally:
# Cleanup code, always runs
cleanup_code()
Example: Using finally
try:
file = open("example.txt", "r") # Opening a file
content = file.read()
except FileNotFoundError:
print("File not found!")
finally:
if 'file' in locals():
file.close() # Ensure the file is closed
print("File has been closed.")
Output:
File not found!
File has been closed.
Explanation:
- If the file is found, it will be read and then closed in the
finally
block. - If the file is not found, the error is caught, but the
finally
block ensures that the cleanup (closing the file, if it was opened) happens anyway.
6. Raising Exceptions Manually
You can also raise exceptions explicitly using the raise
keyword. This allows you to trigger an exception manually when some condition occurs, such as invalid input or failed validation.
Syntax:
raise Exception("This is an error message")
Example: Raising an Exception
def validate_age(age):
if age < 0:
raise ValueError("Age cannot be negative.")
return age
try:
validate_age(-1)
except ValueError as e:
print(e)
Output:
Age cannot be negative.
Explanation:
- The
validate_age
function raises aValueError
if the age is negative. - The exception is caught in the
except
block, and the error message is printed.
7. Custom Exception Classes
You can also create your own exception classes to handle specific types of errors in your program. This is done by subclassing the built-in Exception
class.
Example: Custom Exception Class
class NegativeAgeError(Exception):
pass
def validate_age(age):
if age < 0:
raise NegativeAgeError("Age cannot be negative.")
return age
try:
validate_age(-1)
except NegativeAgeError as e:
print(e)
Output:
Age cannot be negative.
Explanation:
- A custom exception
NegativeAgeError
is created by subclassingException
. - This exception is raised when the age is negative and is caught in the
except
block.