Course Content
Python Indentation, Comments and Variables
0/2
Object Oriented Programming in Python
0/1
Exception Handling in Python
0/1
Sending emails with Python
0/1
Unit test in python programming
0/1
Python programming (zero to advance!!!)
About Lesson

EXCEPTION HANDLING IN PYTHON

THE NEED FOR EXCEPTION HANDLING
Exception handling is a crucial aspect of programming for several reasons:

1. Error Prevention: Exception handling helps prevent your program from crashing when unexpected errors or exceptional conditions occur during execution. Instead of abruptly terminating, your program can gracefully handle errors and continue running, providing a better user experience.

2. Robustness: By handling exceptions, you can make your code more robust and resilient to errors. Even if certain parts of your code encounter problems, exception handling allows you to recover from them and keep your program running smoothly.

3. Debugging and Troubleshooting: Exception messages provide valuable information about what went wrong in your code. By catching and handling exceptions, you can log error messages, trace the source of the problem, and debug your code more effectively.

4. Graceful Recovery: Exception handling enables you to take appropriate actions when errors occur, such as displaying error messages to users, logging diagnostic information for analysis, or retrying failed operations. This allows your program to recover from errors and continue functioning without disruption.

5. Resource Management: Exception handling is essential for managing finite resources, such as file handles, network connections, and database connections. By using `finally` blocks, you can ensure that resources are properly released and cleaned up, even in the event of an exception.

6. Enhancing User Experience: Properly handled exceptions improve the overall user experience of your application by providing meaningful error messages and guiding users on how to resolve issues. This reduces frustration and enhances user satisfaction.

Overall, exception handling is a fundamental programming practice that promotes reliability, stability, and maintainability of software systems. By anticipating and handling errors effectively, you can build more robust and resilient applications that meet the needs of users and stakeholders.

WHAT IS EXCEPTION HANDLING?

Exception handling is a programming construct that allows developers to gracefully manage and respond to errors, exceptions, or unexpected events that may occur during the execution of a program. When a statement or expression in a program encounters an error, it raises an exception, which can disrupt the normal flow of execution. Exception handling provides a mechanism to detect, handle, and recover from these exceptional conditions, allowing the program to continue running without crashing.

The key components of exception handling in most programming languages, including Python, typically include:

1. Try: The `try` block is used to enclose the code that might raise an exception. It is followed by one or more `except` blocks to handle specific types of exceptions that may occur.

2. Except: An `except` block specifies how to handle a specific type of exception raised within the corresponding `try` block. Multiple `except` blocks can be used to handle different types of exceptions, allowing for more precise error handling.

3. Finally: The `finally` block is optional and is used to define cleanup code that should be executed regardless of whether an exception occurred or not. This block is commonly used to release resources or perform cleanup operations.

4. Raise: The `raise` statement is used to manually raise an exception under certain conditions. It allows developers to signal that an error or exceptional condition has occurred, even if it was not automatically detected by the interpreter.

Exception handling provides several benefits, including:

– Preventing program crashes: By handling exceptions, developers can prevent their programs from crashing when errors occur, ensuring smoother execution and better user experience.
– Robustness: Exception handling makes programs more robust and resilient to errors, allowing them to recover gracefully from exceptional conditions.
– Error reporting and logging: Exception handling allows developers to capture and log error messages, making it easier to diagnose and troubleshoot problems in their code.
– Resource cleanup: The `finally` block can be used to ensure that resources, such as file handles or database connections, are properly released, even in the event of an exception.

Overall, exception handling is a critical aspect of programming, enabling developers to write more reliable, stable, and maintainable software.

SYNTAX FOR EXCEPTION HANDLING

In Python, exception handling is implemented using a `try-except` block. The syntax for handling exceptions in Python is as follows:

“`python
try:
      # Code that may raise an exception
      # …
except ExceptionType1:
      # Code to handle ExceptionType1
      # …
except ExceptionType2 as e:
      # Code to handle ExceptionType2
      # Access the exception object using ‘e’
# …
except (ExceptionType3, ExceptionType4):
      # Code to handle multiple exception types together
      # …
except:
      # Code to handle any other exceptions not caught by the above blocks
      # …
else:
     # Optional block that runs if no exceptions are raised in the try block
     # …
finally:
     # Optional block that always runs, regardless of whether an exception occurred
     # Cleanup code or resource release operations can be placed here
     # …
“`

Here are multiple illustrative examples demonstrating different aspects of exception handling in Python:

1. Handling a specific exception:

“`python
try:
     x = int(input(“Enter a number: “))
     result = 10 / x
     print(“Result:”, result)
except ZeroDivisionError:
     print(“Error: Cannot divide by zero”)
“`

2. Handling multiple exceptions:

“`python
try:
      x = int(input(“Enter a number: “))
      result = 10 / x
      print(“Result:”, result)
except (ValueError, ZeroDivisionError):
      print(“Error: Invalid input or cannot divide by zero”)
“`

3. Handling any exception and accessing the exception object:

“`python
try:
     x = int(input(“Enter a number: “))
     result = 10 / x
     print(“Result:”, result)
except Exception as e:
     print(“An error occurred:”, e)
“`

4. Using an `else` block:

“`python
try:
     x = int(input(“Enter a number: “))
     result = 10 / x
except ValueError:
    print(“Error: Invalid input”)
else:
    print(“Division successful”)
    print(“Result:”, result)
“`

5. Using a `finally` block for cleanup:

“`python
try:
     file = open(“example.txt”, “r”)
     print(“File opened successfully”)
    # Code to read from the file
except FileNotFoundError:
    print(“Error: File not found”)
finally:
    file.close() # Close the file regardless of whether an exception occurred
    print(“File closed”)
“`

These examples demonstrate various scenarios of exception handling, including handling specific exceptions, multiple exceptions, accessing exception objects, using `else` and `finally` blocks for additional actions, and ensuring proper cleanup of resources.

Explanation of each part of the syntax:

– `try` block: The code that may raise an exception is placed inside this block.

– `except` block: This block is executed if an exception of the specified type occurs within the `try` block. You can have multiple `except` blocks to handle different types of exceptions. The `ExceptionType` can be a specific built-in exception type (e.g., `ValueError`, `TypeError`) or a generic `Exception` class to catch any exception.

– `as` keyword: Allows you to assign the exception instance to a variable for further processing. This is optional.

– Multiple exception types: You can use a tuple to catch multiple exception types together in a single `except` block.

– `else` block: This block is optional and runs if no exceptions are raised in the `try` block.

– `finally` block: This block is optional and always runs, regardless of whether an exception occurred. It is typically used for cleanup or resource release operations, such as closing files or releasing locks.

By using the `try-except` block, you can gracefully handle exceptions and prevent them from crashing your program. This allows you to write more robust and reliable code that can gracefully handle unexpected errors.

TYPES OF EXCEPTIONS IN PYTHON

In Python, exceptions are categorized into built-in exception classes, each representing different types of errors or exceptional conditions that may occur during program execution. Some common types of exceptions in Python include:

1. SyntaxError:
– Raised when the Python interpreter encounters a syntax error in the code, indicating that the code is not written according to the syntax rules of the language.

# Missing colon after ‘if’ statement
if True
     print(“Hello”)

2. IndentationError:
– Raised when there is an issue with the indentation of the code, such as inconsistent or incorrect indentation levels.

# Inconsistent indentation
def my_function():
print(“Indented incorrectly”)

# Mixing tabs and spaces
def my_function():
print(“Indented with a tab”)

3. NameError:
– Raised when a variable or name is used that has not been defined in the current scope.

# Using a variable that has not been defined
print(undefined_variable)

4. TypeError:
– Raised when an operation or function is applied to an object of an inappropriate type.

# Adding incompatible data types
result = 10 + “5”

# Calling a method on a data type that does not support it
numbers = [1, 2, 3]
numbers.append(4, 5)

5. ValueError:
– Raised when a function receives an argument of the correct type, but with an inappropriate value.

# Converting a string to an integer when the string is not a valid number
number = int(“abc”)

# Trying to access an index that does not exist in a list
my_list = [1, 2, 3]
value = my_list[10]

 

6. KeyError:
– Raised when a dictionary key is not found in the set of existing keys.

# Trying to access a key that does not exist in a dictionary
my_dict = {“a”: 1, “b”: 2}
value = my_dict[“c”]

7. IndexError:
– Raised when a sequence (e.g., list, tuple, or string) index is out of range.

# Trying to access an index that does not exist in a list
my_list = [1, 2, 3]
value = my_list[10]

8. FileNotFoundError:
– Raised when a file or directory is requested, but cannot be found or accessed.

# Trying to open a file that does not exist
with open(“nonexistent_file.txt”, “r”) as f:
       content = f.read()

 

9. IOError:
– Raised when an I/O operation (e.g., reading or writing to a file) fails for some reason.

try:
     file = open(“non_existent_file.txt”, “r”)
except IOError as e:
    print(“An IOError occurred:”, e)

10. ZeroDivisionError:
– Raised when attempting to divide by zero.

try:
      result = 10 / 0
except ZeroDivisionError as e:
      print(“A ZeroDivisionError occurred:”, e)

11. AttributeError:
– Raised when an attribute reference or assignment fails because the specified attribute does not exist.

class MyClass:
def __init__(self):
     self.attribute = “value”

try:
      obj = MyClass()
      print(obj.nonexistent_attribute)
except AttributeError as e:
      print(“An AttributeError occurred:”, e)

12. KeyboardInterrupt:
– Raised when the user interrupts the program’s execution, typically by pressing Ctrl+C.

try:
    while True:
          pass
except KeyboardInterrupt:
     print(“nProgram execution interrupted by the user.”)

 

These are just a few examples of the built-in exception types in Python. There are many other built-in exceptions available in Python, each serving a specific purpose. Understanding these exceptions and how to handle them appropriately is essential for writing robust and reliable Python code.

 

INTENTIONALLY RAISING EXCEPTION
You can deliberately raise an exception in Python using the `raise` keyword followed by the type of exception you want to raise. Here’s an example:

“`python
def calculate_age(year):
      if year < 0:
            raise ValueError(“Year must be a positive integer”)
      return 2024 – year

try:
      age = calculate_age(1990)
      print(“Age:”, age)
except ValueError as e:
      print(“Error:”, e)
“`

In this example, the `calculate_age` function raises a `ValueError` if the `year` parameter is negative. When calling the function with a negative value, it raises the exception, which is caught in the `try` block and handled accordingly.

 

Join the conversation