Python Diaries ….. Day 12
Error Handling 🛠 🛠 🛠
Welcome to Day 12 of Python Diaries! Today, we’ll be exploring the important topic of error handling in Python. Error handling allows you to gracefully handle exceptions or errors that may occur during the execution of your code, preventing them from causing your program to crash.
What is Error Handling?
Error handling is the process of anticipating, detecting, and responding to errors that might occur in your code. In Python, errors are known as exceptions, and they can be caused by a variety of reasons, such as incorrect input, unexpected behavior, or problems with external resources.
Types of Errors
There are three main types of errors in Python:
- Syntax Errors:
- These are errors that occur when the code is not written in a valid Python syntax. They are detected by the Python interpreter when it tries to parse your code.
if x > 5
print("x is greater than 5")
output:
Cell In[1], line 1
if x > 5
^
SyntaxError: expected ':'
2. Logical Errors:
- These errors occur when the code is syntactically correct, but it does not produce the expected result due to a mistake in the logic.
def add_numbers(x, y):
return x - y # Should be x + y
3. Runtime Errors (Exceptions):
- These errors occur during the execution of the code. They are also known as exceptions and can be handled using try-except blocks.
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"Error: {e}")
Exceptions
When an exceptional situation arises, an object representing that situation is created (an exception), and the program flow is altered to handle it.
There are many built-in exception types in Python, such as SyntaxError
, TypeError
, ValueError
, FileNotFoundError
, and many more. Each type of exception represents a different kind of error that can occur during the execution of a program.
SyntaxError: Raised when there is a syntax error in your code (e.g., a typo, missing parenthesis, or incorrect indentation).
# Example with a missing closing parenthesis
try:
result = (4 + 2
except SyntaxError as e:
print(f"SyntaxError: {e}")
IndentationError: Raised when there is an issue with the indentation of your code (e.g., mixing tabs and spaces).
# Example with inconsistent indentation
try:
if True:
print("Indented incorrectly")
except IndentationError as e:
print(f"IndentationError: {e}")
NameError: Raised when a local or global name is not found (i.e., a variable or function name is not defined in the current scope).
# Example with an undefined variable
try:
result = x + 2
except NameError as e:
print(f"NameError: {e}")
TypeError: Raised when an operation or function is applied to an object of inappropriate type.
# Example with trying to add incompatible types
try:
result = "2" + 2
except TypeError as e:
print(f"TypeError: {e}")
ValueError:
Raised when a function receives an argument of the correct data type, but with an inappropriate value.
# Example with converting an inappropriate value to int
try:
result = int("abc")
except ValueError as e:
print(f"ValueError: {e}")
IndexError: Raised when you try to access an index that doesn’t exist in a list, tuple, or other sequence.
# Example with accessing an index that doesn't exist
try:
my_list = [1, 2, 3]
result = my_list[3]
except IndexError as e:
print(f"IndexError: {e}")
KeyError: Raised when you try to access a dictionary with a key that doesn’t exist.
# Example with accessing a non-existent key in a dictionary
try:
my_dict = {'a': 1, 'b': 2}
result = my_dict['c']
except KeyError as e:
print(f"KeyError: {e}")
FileNotFoundError: Raised when an attempt to open a file fails because the file cannot be found.
# Example with trying to open a non-existent file
try:
with open('nonexistent_file.txt', 'r') as file:
content = file.read()
except FileNotFoundError as e:
print(f"FileNotFoundError: {e}")
PermissionError: Raised when you try to access a file or resource without the necessary permissions.
# Example with trying to open a file without proper permissions
try:
with open('/root/some_file.txt', 'w') as file:
file.write("Some data")
except PermissionError as e:
print(f"PermissionError: {e}")
ZeroDivisionError: Raised when you try to divide a number by zero.
# Example with dividing by zero
try:
result = 5 / 0
except ZeroDivisionError as e:
print(f"ZeroDivisionError: {e}")
Raising Exceptions
You can explicitly raise an exception using the raise
statement. This is useful when you want to signal that a certain condition has occurred that requires special handling.
if condition_not_met:
raise ValueError("Invalid input")
Catching Exceptions
To handle exceptions, you use a try
-except
block. The code that might raise an exception is placed in the try
block. If an exception occurs, the code in the except
block is executed.
try:
# Code that might raise an exception
except SomeException as e:
# Code to handle the exception
SomeException
is the type of exception you expect to occur. You can catch specific exceptions or use a broader Exception
class to catch any exception.
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"Error: {e}")
Handling Multiple Exceptions:
You can handle multiple types of exceptions by using multiple except
blocks or by using a tuple of exception types in a single except
block.
try:
# Code that might raise an exception
except (ExceptionType1, ExceptionType2) as e:
# Code to handle ExceptionType1 or ExceptionType2
Example with multiple blocks:
try:
file = open("nonexistent_file.txt", "r")
except FileNotFoundError as e:
print(f"Error: {e}")
except IOError as e:
print(f"IO Error: {e}")
you can change it as follows:
try:
file = open("nonexistent_file.txt", "r")
except (FileNotFoundError, IOError) as e:
print(f"Error: {e}")
else
and finally
Blocks:
You can optionally include an else
block after the try
block. Code in the else
block will be executed if no exceptions are raised.
The finally
block is used for code that should be executed regardless of whether an exception occurred or not. This block is often used for cleanup operations.
try:
# Code that might raise an exception
except SomeException as e:
# Code to handle the exception
else:
# Code to execute if no exceptions were raised
finally:
# Code to execute regardless of exceptions
Custom Exceptions:
You can create your own exception classes by inheriting from the built-in Exception
class. This allows you to define specific types of exceptions that are relevant to your application.
class CustomError(Exception):
pass
try:
if condition_not_met:
raise CustomError("Custom error message")
except CustomError as e:
# Handle the custom exception
Logging Exceptions:
You can log exceptions using the logging
module, which allows you to record information about when and where an exception occurred.
import logging
try:
# Code that might raise an exception
except SomeException as e:
logging.exception("An error occurred")
Error handling is a crucial aspect of writing robust and reliable Python code. It allows you to gracefully handle exceptions and prevent them from causing your program to crash. By using try-except blocks, you can anticipate and respond to different types of errors that may occur during the execution of your code. You can access the other topics in this tutorial series right here:
- Day 1: Data types, Comment, Type casting and User input.
- Day 2: Numbers, Strings, and Booleans.
- Day 3: Operators
- Day 4: Lists
- Day 5: Tuples and Sets
- Day 6: Dictionaries
- Day 7: If , If Else, If elif else Condition statements
- Day 8: While loops
- Day 9: For loops
- Day 10: Functions
- Day 11: File handling
- Day 12: Error Handling
- Day 13: Regular expressions
- Day 14: OOPS in python (class)
- Day 15: Python GUI libraries
In Day 13, we’ll explore the concept of Regular expressions. Keep up the great work! Happy coding!