Has anyone of you ever compiled some code only to find that the program is not working because of some stupid bug? Well, we all have faced this problem in our programming journey.
It is obvious that anyone may get errors in their code. So, this highlights the importance of knowing how to handle these errors in Python.
Basically, when we talk of exception handling in Python, we talk of ways in which the errors can be treated without affecting the functionality of your program. Otherwise, it is possible that our programs will simply terminate with an exception without an expected action.
In this article, we will discuss some of the core concepts of exception handling and explore some of the key approaches and concepts that are significant to every Python developer.
Difference Between Errors and Exceptions in Python
Errors and exceptions are used in similar contexts, and many times, people get confused between both, but they are different.
The error means something is wrong with how the code is written. There are some specific sets of rules for the right codes in Python; if they are not followed, it can cause syntax errors. They prevent the code from running. For example, forgetting a colon after an if statement—that's a syntax error.
On the other hand, exceptions arise during program execution. They occur when something goes wrong with the syntactically correct code. Examples include division by zero and opening a file that does not exist.
Here’s an example of a syntax error:
# Incorrect code without the colon
if True
print("This will cause a syntax error")
|
And here’s an example of an exception:
# Correct syntax, but will cause a runtime exception
a = 10 / 0
|
Common Types of Exceptions in Python
When one does programming with Python, several built-in exceptions can occur. Here are some common ones:
-
SyntaxError: Error in the syntax of the code.
-
TypeError: Operation or function is applied to an object of an inappropriate type.
-
NameError: A variable or function name is not found.
-
IndexError: An index is out of range.
-
KeyError: A key is not found in a dictionary.
-
ValueError: An invalid value is used.
-
AttributeError: An attribute reference or assignment fails.
-
IOError: Input/output operation fails.
-
ZeroDivisionError: Division by zero is attempted.
-
ImportError: Importing a module fails.
For instance, let's say we want to access an element from a list that doesn't exist:
# This will cause an IndexError
my_list = [1, 2, 3]
print(my_list[5])
|
Implementing Basic Exception Handling with try and except Blocks
Programming with Python allows us to handle exceptions using try and except blocks. The try block contains code that might throw an exception.
If an exception occurs, the code in the except block executes. Here’s a basic example:
try:
user_input = int(input("Enter a number: "))
result = 10 / user_input
print("The result is:", result)
except ZeroDivisionError:
print("You can't divide by zero!")
except ValueError:
print("That's not a valid number!")
|
In this code:
-
If the user enters zero, a ZeroDivisionError is caught.
-
If the user enters something that isn't a number, a ValueError is caught.
Output Table:
Input
|
Output
|
5
|
The result is: 2.0
|
0
|
You can't divide by zero!
|
text
|
That's not a valid number!
|
Handling Multiple Exceptions with Multiple except Blocks
Sometimes, we need to handle more than one type of exception. Python allows us to catch multiple exceptions using multiple except blocks.
Using multiple except blocks ensures that specific exceptions are caught and handled appropriately. This keeps our programs running smoothly, even when unexpected issues arise.
Here’s how it works:
try:
index = int(input("Enter an index: "))
value = int(input("Enter a number: "))
my_list = [10, 20, 30]
print("The value is:", my_list[index] / value)
except IndexError:
print("Index out of range!")
except ZeroDivisionError:
print("You can't divide by zero!")
except ValueError:
print("Invalid input!")
|
Output Table:
Input (Index)
|
Input (Number)
|
Output
|
1
|
2
|
The value is: 10.0
|
5
|
2
|
Index out of range!
|
1
|
0
|
You can't divide by zero!
|
text
|
2
|
Invalid input!
|
Using else and finally Clauses in Exception Handling
Do you worry about what happens if an error doesn’t occur but you still need to run some code? The else and finally clauses are here to help.
-
The else clause runs if no exceptions occur in the try block.
-
The finally clause always runs, whether an exception occurs or not.
This ensures cleanup actions are executed no matter what.
Here’s an example:
try:
number = int(input("Enter a number: "))
result = 10 / number
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print("The result is:", result)
finally:
print("This will always execute.")
|
Output Table:
Input
|
Output
|
2
|
The result is: 5.0
This will always execute.
|
0
|
You can't divide by zero!
This will always execute.
|
Using else helps keep the try block clean by running specific code only if no exceptions are thrown. The finally clause is perfect for tasks like closing files or releasing resources.
Raising Exceptions Manually in Python
Sometimes, we need to raise exceptions ourselves. Using the raise statement, we can create exceptions if a condition is met.
Raising exceptions manually makes our code more robust and easier to debug. This helps enforce rules and catch potential issues early.
Here’s how:
def check_age(age):
if age < 18:
raise ValueError("Age must be 18 or older.")
return "Access granted."
try:
user_age = int(input("Enter your age: "))
print(check_age(user_age))
except ValueError as e:
print(e)
|
Output Table:
Input
|
Output
|
20
|
Access granted.
|
15
|
Age must be 18 or older.
|
Creating Custom Exceptions for Specific Scenarios
There are times when built-in exceptions aren’t enough. We can create custom exceptions to handle specific situations.
Custom exceptions make our error messages more meaningful. This improves debugging and helps others understand what went wrong.
Here's how we define a custom exception:
class EmptyListError(Exception):
pass
def get_first_element(lst):
if not lst:
raise EmptyListError("The list is empty.")
return lst[0]
try:
items = []
print(get_first_element(items))
except EmptyListError as e:
print(e)
|
Output Table:
Input List
|
Output
|
[1, 2, 3]
|
1
|
[]
|
The list is empty.
|
Advantages and Disadvantages of Exception Handling in Python
Advantages
-
Improved Program Reliability: Prevents crashes from unexpected errors.
-
Simplified Error Handling: Separates error handling from main logic.
-
Cleaner Code: Avoids complex conditional statements.
-
Easier Debugging: Tracebacks show where exceptions occurred.
Disadvantages
-
Performance Overhead: Handling exceptions can slow down execution.
-
Increased Code Complexity: Multiple exceptions can complicate code.
-
Potential Security Risks: Poor handling can expose sensitive information.
Balancing these pros and cons helps us use exception handling effectively.
Conclusion
In this blog, we have explained the basic concepts of exception handling in Python and their practical implementations. We covered the basics of try, except, else, and finally blocks.
We discussed raising and catching both built-in and custom exceptions. Understanding these concepts helps us write robust and error-resistant code.
By following best practices like being specific with exceptions, using finally for cleanup, and documenting custom exceptions, we ensure our programs remain stable and maintainable.
Mastering these techniques makes programming with Python smoother and more enjoyable.
Thank you for giving your 5 minute :)