Exceptions
Exceptions and Exception Handling in Python
In Python, exceptions are errors that occur during the execution of a program, disrupting the normal flow of instructions. When an exception occurs, Python stops the normal flow of the program and looks for an exception handler to deal with the error. If no handler is found, the program will terminate.
Exception Handling in Python allows us to anticipate these errors and handle them gracefully instead of letting the program crash.
1. Basic Structure of Exception Handling
Python provides a mechanism to handle exceptions using the try, except, else, and finally blocks.
Syntax:
try:
# Code that may raise an exception
except <ExceptionType>:
# Code to handle the exception
else:
# Code that will execute if no exception occurred
finally:
# Code that will always execute, regardless of whether an exception occurred or notExplanation of Blocks:
try: You write the code that may cause an exception here.except: If an exception occurs, the code in this block is executed. You can specify the type of exception to catch.else: If no exception occurs in thetryblock, the code in theelseblock will run.finally: This block runs no matter what, whether an exception occurred or not. It's typically used for cleanup actions (like closing files or releasing resources).
2. Example of Basic Exception Handling
try:
x = int(input("Enter a number: ")) # This may raise a ValueError
result = 10 / x # This may raise a ZeroDivisionError
except ZeroDivisionError:
print("Error: Cannot divide by zero!")
except ValueError:
print("Error: Invalid input, please enter a number!")
else:
print(f"Result is: {result}")
finally:
print("Execution completed.")Output:
Enter a number: 0
Error: Cannot divide by zero!
Execution completed.In this example:
- If the user enters
0, aZeroDivisionErrorwill occur. - If the user enters something that can't be converted to an integer (like a string), a
ValueErrorwill be raised. - The
finallyblock will always execute.
3. Catching Multiple Exceptions
You can catch multiple exceptions in a single except block by specifying them in a tuple.
try:
x = int(input("Enter a number: "))
result = 10 / x
except (ZeroDivisionError, ValueError) as e:
print(f"An error occurred: {e}")
else:
print(f"Result is: {result}")
finally:
print("Execution completed.")In this example, both ZeroDivisionError and ValueError are handled in one block.
4. Handling Specific Exception Types
You can handle different types of exceptions with multiple except blocks to target specific exceptions.
try:
a = int(input("Enter a number: "))
b = int(input("Enter another number: "))
result = a / b
except ZeroDivisionError:
print("Error: Cannot divide by zero!")
except ValueError:
print("Error: Invalid input, please enter a valid number!")
except Exception as e:
print(f"Unexpected error: {e}")
else:
print(f"Result is: {result}")
finally:
print("Execution completed.")Here:
ZeroDivisionErrorhandles division by zero.ValueErrorhandles invalid input.Exceptioncatches any other unforeseen errors.
5. Raising Exceptions
In Python, you can also raise exceptions manually using the raise keyword. This allows you to trigger exceptions based on custom conditions.
def validate_age(age):
if age < 18:
raise ValueError("Age must be 18 or older.")
return "Age is valid."
try:
age = int(input("Enter your age: "))
print(validate_age(age))
except ValueError as e:
print(f"Error: {e}")In this example, if the user enters an age less than 18, a ValueError will be raised with a custom message.
6. Custom Exceptions
You can define your own exceptions by subclassing the built-in Exception class.
Example:
class NegativeValueError(Exception):
"""Custom exception for negative values."""
pass
def check_value(value):
if value < 0:
raise NegativeValueError("Value cannot be negative.")
return "Value is valid."
try:
value = int(input("Enter a value: "))
print(check_value(value))
except NegativeValueError as e:
print(f"Error: {e}")In this example, NegativeValueError is a custom exception. If the user enters a negative number, this exception will be raised.
7. The else and finally Blocks
- The
elseblock is executed if no exception is raised in thetryblock. It's often used to run code that should only execute if thetryblock succeeds. - The
finallyblock is executed no matter what, even if an exception was raised or not. It's commonly used for clean-up operations, like closing files or releasing resources.
Example:
try:
file = open("test.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found!")
else:
print("File contents successfully read.")
print(content)
finally:
print("Closing the file.")
file.close() # Ensure the file is closed regardless of success or failure8. Common Built-in Exceptions in Python
Here are some common built-in exceptions in Python:
ValueError: Raised when a function receives an argument of the correct type but an inappropriate value.TypeError: Raised when an operation or function is applied to an object of inappropriate type.IndexError: Raised when a sequence subscript is out of range.KeyError: Raised when a dictionary key is not found.FileNotFoundError: Raised when trying to open a file that does not exist.ZeroDivisionError: Raised when dividing by zero.NameError: Raised when a local or global name is not found.AttributeError: Raised when an invalid attribute reference is made.
Example:
try:
num = int(input("Enter a number: ")) # Could raise ValueError
result = 10 / num # Could raise ZeroDivisionError
except ZeroDivisionError as e:
print(f"Error: {e}")
except ValueError as e:
print(f"Error: {e}")Summary
- Exceptions in Python are errors that disrupt the normal flow of execution.
- You handle exceptions using the
try,except,else, andfinallyblocks. - The
tryblock contains code that might raise an exception. - The
exceptblock handles the exception if one occurs. - The
elseblock runs if no exception occurs in thetryblock. - The
finallyblock always runs, regardless of whether an exception occurred. - You can raise exceptions using
raiseand create custom exceptions by subclassing theExceptionclass.