Paramclasses Academy - Blog

Tutorials Details

←
Post 14 of 20
→

Python File Handling: Read, Write, Append & File Operations

Python File Handling: Read, Write, Append & File Operations

October 17, 2026

Python File Handling: Read, Write, Append and File Operations

Introduction to Python File Handling

File handling in Python allows programs to create, open, read, write, update, and manage files. It is useful when information needs to be stored permanently instead of disappearing when a program finishes running.

For example, a student management system can save student records in a file, a billing application can store invoices, and a logging system can record events and errors.

In this tutorial, you will learn how to open files, use different file modes, read and write text, work with CSV and JSON files, handle file errors, and build a practical file-based application.

1. What Is File Handling in Python?

File handling is the process of interacting with files stored on a computer.

Python provides the built-in open() function to open files.

The general syntax is:

file = open("filename.txt", "mode")

Here:

  • open() opens a file.

  • "filename.txt" specifies the file path.

  • "mode" determines how the file will be accessed.

  • The returned file object provides methods for reading or writing.

A safer and recommended approach is to use the with statement, which automatically closes the file when the block finishes.

with open("example.txt", "w", encoding="utf-8") as file:
    file.write("Welcome to Python File Handling!")

This example creates or overwrites example.txt and writes the given text into it.

Important: Write mode ("w") replaces existing content if the file already exists.

2. Different File Modes in Python

File modes determine what operations can be performed on a file.

Mode Description
"r" Opens an existing file for reading.
"w" Opens a file for writing and truncates existing content, or creates it if missing.
"a" Opens a file for appending at the end, or creates it if missing.
"x" Creates a new file and raises an error if it already exists.
"b" Adds binary mode, such as "rb" or "wb".
"t" Text mode; this is the default mode.
"r+" Opens an existing file for reading and writing without truncating it.
"w+" Opens a file for reading and writing, truncating existing content or creating a new file.
"a+" Opens a file for reading and appending, creating it if necessary.

Example: Using Read Mode

with open("example.txt", "r", encoding="utf-8") as file:
    content = file.read()
    print(content)

The file must already exist, or Python will raise a FileNotFoundError.

Example: Using Write Mode

with open("example.txt", "w", encoding="utf-8") as file:
    file.write("This is a new message.")

This replaces the previous content of the file.

Example: Using Append Mode

with open("example.txt", "a", encoding="utf-8") as file:
    file.write("\nThis message is added at the end.")

Append mode preserves the existing content and adds new content at the end.

3. How to Create a File in Python

Python can create a file when it is opened using modes such as "w", "a", or "x".

Example

with open("myfile.txt", "w", encoding="utf-8") as file:
    file.write("My first Python file.")

print("File created successfully.")

Output:

File created successfully.

The file is created relative to the program's current working directory unless a different path is provided.

To avoid accidentally overwriting an existing file, use exclusive creation mode "x".

with open("newfile.txt", "x", encoding="utf-8") as file:
    file.write("This file must not already exist.")

If newfile.txt already exists, Python raises a FileExistsError.

4. How to Read a File in Python

Python offers multiple methods for reading file content.

A. The read() Method

The read() method reads the contents of a file and returns them as a string in text mode.

with open("example.txt", "r", encoding="utf-8") as file:
    content = file.read()

print(content)

You can also pass a size argument to read a limited number of characters.

with open("example.txt", "r", encoding="utf-8") as file:
    content = file.read(10)

print(content)

This reads up to 10 characters from the file.

B. The readline() Method

The readline() method reads one line at a time.

with open("students.txt", "r", encoding="utf-8") as file:
    first_line = file.readline()
    second_line = file.readline()

print(first_line, end="")
print(second_line, end="")

This reads the first two lines, provided they exist.

C. The readlines() Method

The readlines() method returns the remaining lines as a list of strings.

with open("students.txt", "r", encoding="utf-8") as file:
    lines = file.readlines()

print(lines)

Each list item normally includes its newline character when one is present in the file.

D. Read a File Using a Loop

For large text files, iterating over the file object is often more memory-efficient than reading the entire file into one string.

with open("students.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line, end="")

This processes the file one line at a time.

5. How to Write to a File in Python

The write() method writes a string to a file.

with open("message.txt", "w", encoding="utf-8") as file:
    file.write("Hello, Python!\n")
    file.write("Learning file handling is easy.")

print("Data written successfully.")

Output:

Data written successfully.

The file contains:

Hello, Python!
Learning file handling is easy.

The write() method does not automatically add a newline. Use "\n" when you want to start a new line.

Writing Multiple Lines With writelines()

The writelines() method writes an iterable of strings to a file. It does not automatically add newline characters between the strings.

lines = [
    "Python\n",
    "Java\n",
    "JavaScript\n"
]

with open("languages.txt", "w", encoding="utf-8") as file:
    file.writelines(lines)

File content:

Python
Java
JavaScript

6. How to Append Data to a File

Append mode adds new content without deleting existing content.

with open("activity.txt", "a", encoding="utf-8") as file:
    file.write("User logged in.\n")
    file.write("Task completed.\n")

Each execution appends these lines to the file.

Append mode is useful for logs, activity records, and simple history files.

Remember that append mode does not automatically insert a newline before new content. Add "\n" when required.

7. Using the with Statement

The with statement is recommended because it manages file cleanup automatically.

Without with

file = open("example.txt", "r", encoding="utf-8")

try:
    content = file.read()
    print(content)
finally:
    file.close()

With with

with open("example.txt", "r", encoding="utf-8") as file:
    content = file.read()
    print(content)

The second approach is shorter and closes the file automatically when the block exits, even if an exception occurs.

Best practice: Prefer with open(...) for normal file operations.

8. File Pointer and File Position

A file object maintains a current position indicating where the next read or write operation will occur.

Python provides two useful methods:

  • tell() returns the current file position.

  • seek() changes the file position.

Example

with open("example.txt", "r", encoding="utf-8") as file:
    print(file.read(5))
    print("Current position:", file.tell())

    file.seek(0)
    print(file.read(5))

The second read starts from the beginning because seek(0) resets the position.

In text mode, file positions can have special constraints. Seeking to the beginning with seek(0) is a common and safe operation.

9. Working With Binary Files

Binary files contain bytes rather than decoded text. Examples include images, PDFs, audio files, and other non-text data.

Use binary modes such as "rb" and "wb" to read and write bytes.

Example: Copying a Binary File

with open("source.jpg", "rb") as source:
    with open("copy.jpg", "wb") as destination:
        while True:
            chunk = source.read(8192)

            if not chunk:
                break

            destination.write(chunk)

print("File copied successfully.")

This example copies an image in chunks rather than loading the entire file into memory.

The source file must exist, and the program must have permission to read it and write the destination.

10. File Handling With Exception Handling

File operations can fail for several reasons, including missing files, permission restrictions, and invalid paths.

Python's try and except statements allow you to handle expected errors.

Example: Handling a Missing File

try:
    with open("missing.txt", "r", encoding="utf-8") as file:
        content = file.read()
        print(content)

except FileNotFoundError:
    print("Error: The requested file was not found.")

except PermissionError:
    print("Error: You do not have permission to access this file.")

If the file does not exist, the program displays an error message instead of terminating with an unhandled exception.

Best Practices for Error Handling

  1. Catch specific exceptions whenever possible.

  2. Avoid using a bare except: unless there is a compelling reason.

  3. Use clear error messages.

  4. Do not silently ignore important file errors.

  5. Avoid overwriting important data without confirmation.

  6. Validate file paths when accepting them from users.

11. Working With File Paths Using pathlib

Python's pathlib module provides an object-oriented way to work with filesystem paths.

It can help you create paths, check whether files exist, and read or write text.

Example

from pathlib import Path

file_path = Path("notes.txt")

file_path.write_text(
    "Learning Python file handling.",
    encoding="utf-8"
)

content = file_path.read_text(encoding="utf-8")

print(content)
print("File exists:", file_path.exists())

Output:

Learning Python file handling.
File exists: True

Path.write_text() replaces the file's existing text content if the file already exists. Use it carefully when working with important files.

Checking Whether a File Exists

from pathlib import Path

file_path = Path("notes.txt")

if file_path.exists() and file_path.is_file():
    print("The file exists.")
else:
    print("The file does not exist.")

Using pathlib can make file-path operations more readable and portable across operating systems.

12. Working With CSV Files in Python

CSV stands for Comma-Separated Values. CSV files are commonly used to store tabular data such as student records, product lists, and reports.

Python provides the built-in csv module.

Writing CSV Data

import csv

students = [
    ["Name", "Age", "Marks"],
    ["Rahul", 21, 85],
    ["Priya", 22, 92],
    ["Amit", 20, 78]
]

with open("students.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerows(students)

print("CSV file created successfully.")

The newline="" argument is recommended when opening CSV files for writing with Python's csv module.

Reading CSV Data

import csv

with open("students.csv", "r", newline="", encoding="utf-8") as file:
    reader = csv.reader(file)

    for row in reader:
        print(row)

Output:

['Name', 'Age', 'Marks']
['Rahul', '21', '85']
['Priya', '22', '92']
['Amit', '20', '78']

CSV readers normally return each field as a string. Convert values to numbers when numerical calculations are required.

Using DictReader

DictReader allows you to access CSV rows using column names.

import csv

with open("students.csv", "r", newline="", encoding="utf-8") as file:
    reader = csv.DictReader(file)

    for student in reader:
        print(student["Name"], student["Marks"])

Output:

Rahul 85
Priya 92
Amit 78

13. Working With JSON Files in Python

JSON stands for JavaScript Object Notation. It is a common format for exchanging structured data between applications and APIs.

Python provides the built-in json module for working with JSON.

Writing JSON Data

import json

student = {
    "name": "Rahul",
    "age": 21,
    "marks": 85,
    "subjects": ["Python", "Database", "Web Development"]
}

with open("student.json", "w", encoding="utf-8") as file:
    json.dump(student, file, indent=4)

print("JSON file created successfully.")

The indent=4 argument makes the JSON output easier to read.

Reading JSON Data

import json

with open("student.json", "r", encoding="utf-8") as file:
    student = json.load(file)

print(student["name"])
print(student["marks"])
print(student["subjects"])

Output:

Rahul
85
['Python', 'Database', 'Web Development']

json.dump() vs json.dumps()

  • json.dump() writes JSON data directly to a file object.

  • json.dumps() converts a Python object into a JSON-formatted string.

Similarly:

  • json.load() reads JSON data from a file object.

  • json.loads() parses a JSON-formatted string.

Important JSON Security Note

Only load JSON from trusted or appropriately validated sources when the data will influence your application. JSON parsing does not execute arbitrary Python code, but untrusted data can still contain invalid or misleading values that your program must validate.

14. Practical Project: Student Record Manager

Let's create a simple program that saves student records in a JSON file and reads them later.

This example demonstrates persistent storage using file handling.

import json
from pathlib import Path

FILE_PATH = Path("students.json")


def load_students():
    if not FILE_PATH.exists():
        return []

    try:
        with FILE_PATH.open("r", encoding="utf-8") as file:
            data = json.load(file)

        if not isinstance(data, list):
            raise ValueError("Student data must be a list.")

        return data

    except json.JSONDecodeError:
        print("Error: The JSON file contains invalid data.")
        return []


def save_students(students):
    with FILE_PATH.open("w", encoding="utf-8") as file:
        json.dump(students, file, indent=4)


def add_student():
    name = input("Enter student name: ").strip()
    marks_text = input("Enter student marks (0-100): ").strip()

    if not name:
        print("Student name cannot be empty.")
        return

    try:
        marks = float(marks_text)
    except ValueError:
        print("Please enter a valid number for marks.")
        return

    if not 0 <= marks <= 100:
        print("Marks must be between 0 and 100.")
        return

    students = load_students()

    students.append({
        "name": name,
        "marks": marks
    })

    save_students(students)
    print("Student record saved successfully.")


def show_students():
    students = load_students()

    if not students:
        print("No student records found.")
        return

    for index, student in enumerate(students, start=1):
        print(
            f"{index}. {student['name']} - "
            f"{student['marks']} marks"
        )


def main():
    while True:
        print("\n--- Student Record Manager ---")
        print("1. Add Student")
        print("2. Show Students")
        print("3. Exit")

        choice = input("Choose an option: ").strip()

        if choice == "1":
            add_student()
        elif choice == "2":
            show_students()
        elif choice == "3":
            print("Program closed.")
            break
        else:
            print("Invalid choice. Please try again.")


if __name__ == "__main__":
    main()

How This Project Works

  1. The program checks whether students.json exists.

  2. The load_students() function reads existing records.

  3. The add_student() function collects input and validates the name and marks.

  4. The save_students() function writes records to the JSON file.

  5. The show_students() function displays saved records.

  6. The main() function provides a menu for interacting with the application.

Note: This is a learning project. A production application should include stronger data validation, robust error recovery, backup handling, and protection against concurrent file updates.

15. Common File Handling Mistakes

Mistake 1: Opening a Missing File in Read Mode

with open("missing.txt", "r", encoding="utf-8") as file:
    print(file.read())

If the file does not exist, Python raises FileNotFoundError.

Solution: Check the file path or handle the exception.

Mistake 2: Accidentally Overwriting Data

Using "w" truncates an existing file.

Solution: Use "a" to append content or "x" to create a file only if it does not already exist.

Mistake 3: Forgetting to Close a File

Files left open unnecessarily can consume resources.

Solution: Use with open(...) so the file is closed automatically.

Mistake 4: Incorrect Encoding

Reading a text file with an incompatible encoding may cause a UnicodeDecodeError.

Solution: Specify the expected encoding, commonly encoding="utf-8" for files created as UTF-8.

Mistake 5: Assuming the File Is in the Script Directory

Relative paths are generally interpreted relative to the current working directory, which may not be the directory containing the script.

Solution: Check the working directory or build an explicit path using pathlib.

Mistake 6: Forgetting Newline Characters

The write() and writelines() methods do not automatically separate text into lines.

Solution: Add "\n" where needed.

16. Python File Handling Practice Programs

Practice these exercises to improve your file-handling skills:

  1. Create a text file and write five lines into it.

  2. Read and display the contents of an existing text file.

  3. Count the number of lines in a text file.

  4. Count the words and characters in a file.

  5. Append a new line to an existing file.

  6. Copy the contents of one text file to another.

  7. Handle a missing file using try and except.

  8. Save student records in a CSV file.

  9. Store product information in a JSON file.

  10. Build a contact book that saves names and phone numbers in a file.

  11. Create a log file that records program activities.

  12. Build a student record manager that can add and display saved records.

17. Python File Handling Interview Questions

Q1. What is file handling in Python?

File handling allows a program to create, read, write, append, and manage files.

Q2. Which function is used to open a file?

The built-in open() function.

Q3. What is the difference between "w" and "a" mode?

"w" truncates existing content or creates a new file, while "a" adds content at the end or creates a missing file.

Q4. What is the difference between read() and readline()?

read() reads all remaining content or a specified number of characters, while readline() reads one line.

Q5. What is the purpose of with open()?

It automatically closes the file when the block finishes.

Q6. What does write() do?

It writes a string to a text file and returns the number of characters written.

Q7. What is the difference between text and binary modes?

Text mode works with strings and encoding, while binary mode works with bytes.

Q8. What is FileNotFoundError?

It is an exception raised when an operation requiring a file cannot find the specified file.

Q9. What are seek() and tell()?

tell() reports the current file position, while seek() changes that position.

Q10. What is the CSV module?

It is a built-in Python module for reading and writing CSV data.

Q11. What is JSON?

JSON is a text-based data format commonly used to exchange structured data between applications.

Q12. What is the difference between json.dump() and json.dumps()?

json.dump() writes JSON to a file object, whereas json.dumps() returns JSON as a string.

Conclusion

Python file handling is an important skill for building applications that need to store and retrieve information. By learning file modes, reading, writing, appending, exception handling, file paths, CSV, and JSON, you can create programs that work with persistent data.

Start with simple text files, then practise CSV and JSON operations before building larger applications. These skills will also help when working with databases, APIs, logging systems, and real-world Python projects.

Python File Handling: Read, Write, Append & File Operations

Python File Handling: Read, Write, Append & File Operations

October 17, 2026

Python Exception Handling: Try, Except, Finally and Custom Exceptions

Introduction to Exception Handling in Python

Exception handling in Python is a technique for managing errors that occur while a program is running. It helps developers handle unexpected situations without allowing the application to terminate unnecessarily.

For example, a program may encounter an invalid number, a missing file, a division-by-zero operation, or an unsuccessful database connection. Exception handling allows the program to respond to such situations in a controlled way.

In this tutorial, you will learn about exceptions, try, except, else, finally, the raise keyword, built-in exceptions, custom exceptions, and practical examples.

1. What Is an Exception in Python?

An exception is an event that occurs during program execution and interrupts the normal flow of instructions.

Consider the following example:

number = 10 / 0

print(number)

Output:

ZeroDivisionError: division by zero

Python raises a ZeroDivisionError because division by zero is not allowed for ordinary numeric division.

The print() statement does not execute because the exception interrupts the program.

Exception handling allows you to catch and respond to such errors.

2. What Is the Difference Between an Error and an Exception?

The terms error and exception are sometimes used informally in similar ways, but they can describe different situations.

  • Syntax error: The code violates Python's syntax rules.

  • Exception: An event occurs during execution that can often be handled using try and except.

  • Logical error: The program runs but produces an incorrect result because the logic is wrong.

Example of a Syntax Error

if True
    print("Hello")

The colon is missing after True, so Python reports a SyntaxError.

Example of a Runtime Exception

number = int("hello")

This raises a ValueError because "hello" cannot be converted into an integer.

Example of a Logical Error

length = 10
width = 5

area = length + width
print(area)

Output:

15

The program runs, but the correct rectangle area calculation should multiply length by width, not add them.

Exception handling does not automatically fix syntax or logical errors.

3. The try and except Blocks

Python uses try and except to handle exceptions.

  • The try block contains code that may raise an exception.

  • The except block contains code that runs when a matching exception occurs.

Syntax

try:
    # Code that may raise an exception
    pass
except SomeException:
    # Error-handling code
    pass

Example: Handling Division by Zero

try:
    number = 10 / 0
    print(number)
except ZeroDivisionError:
    print("Error: Cannot divide by zero.")

Output:

Error: Cannot divide by zero.

Instead of stopping with an unhandled exception, the program displays a meaningful message.

4. Handling Multiple Exceptions

A program may encounter different types of exceptions. Python allows you to handle each type separately.

try:
    number = int(input("Enter a number: "))
    result = 100 / number
    print("Result:", result)

except ValueError:
    print("Please enter a valid integer.")

except ZeroDivisionError:
    print("The number cannot be zero.")

Example output when the user enters 0:

Enter a number: 0
The number cannot be zero.

Example output when the user enters abc:

Enter a number: abc
Please enter a valid integer.

Handling specific exceptions helps the program display appropriate messages for different problems.

Handling Multiple Exception Types Together

You can use a tuple of exception classes when the same handling logic applies to multiple exceptions.

try:
    number = int(input("Enter an integer: "))
    print(100 / number)

except (ValueError, ZeroDivisionError):
    print("Please enter a valid, non-zero integer.")

This approach is useful when different exceptions require the same response.

5. The else Block in Exception Handling

The else block runs only when the try block completes without raising an exception.

Example

try:
    number = int(input("Enter a number: "))
    result = 100 / number

except ValueError:
    print("Invalid number.")

except ZeroDivisionError:
    print("Cannot divide by zero.")

else:
    print("Result:", result)

Example output:

Enter a number: 5
Result: 20.0

The else block is useful for separating successful operations from error-handling logic.

6. The finally Block in Python

The finally block runs when control leaves the associated try statement, whether an exception occurred or not.

It is often used for cleanup tasks, such as releasing resources.

Example

try:
    number = 10 / 2
    print("Result:", number)

except ZeroDivisionError:
    print("Cannot divide by zero.")

finally:
    print("Operation finished.")

Output:

Result: 5.0
Operation finished.

The finally block also runs if an exception occurs:

try:
    number = 10 / 0

except ZeroDivisionError:
    print("Cannot divide by zero.")

finally:
    print("Cleanup completed.")

Output:

Cannot divide by zero.
Cleanup completed.

The finally block is useful for cleanup, but it is not a replacement for proper resource management. For files, the with statement is generally preferred.

7. Using try, except, else, and finally Together

All four blocks can be used in one exception-handling structure.

try:
    number = int(input("Enter a number: "))
    result = 100 / number

except ValueError:
    print("Invalid input. Enter an integer.")

except ZeroDivisionError:
    print("Division by zero is not allowed.")

else:
    print("Calculation successful.")
    print("Result:", result)

finally:
    print("Program operation completed.")

Example output when the user enters 4:

Enter a number: 4
Calculation successful.
Result: 25.0
Program operation completed.

Each block has a different purpose:

  • try: Executes the main operation.

  • except: Handles matching exceptions.

  • else: Runs if the try block succeeds.

  • finally: Runs during normal cleanup as control leaves the structure.

8. Common Built-in Exceptions in Python

Python provides many built-in exception classes.

Exception Description
ZeroDivisionError Division by zero.
ValueError A value has an inappropriate form for an operation.
TypeError An operation or function receives an inappropriate type.
NameError A name cannot be found in the current scope.
IndexError A sequence index is out of range.
KeyError A dictionary key is not found.
FileNotFoundError A requested file cannot be found.
ImportError An import operation fails.
AttributeError An object does not have the requested attribute.
ModuleNotFoundError A requested module cannot be found.
PermissionError An operation is denied due to insufficient permissions.
RuntimeError A general runtime problem that does not fit a more specific built-in exception.

Examples

ValueError

number = int("abc")

TypeError

result = "Age: " + 25

IndexError

numbers = [10, 20, 30]
print(numbers[5])

KeyError

student = {"name": "Rahul"}
print(student["age"])

Understanding exception types helps you write more precise error-handling code.

9. Using the raise Keyword

The raise keyword allows a programmer to raise an exception deliberately when a condition is invalid.

Example: Validating Age

age = int(input("Enter your age: "))

if age < 0:
    raise ValueError("Age cannot be negative.")

print("Age:", age)

If the user enters a negative age, Python raises a ValueError with a custom message.

You can also raise an exception inside a function.

def calculate_square_root_input(number):
    if number < 0:
        raise ValueError("Number must not be negative.")

    return number ** 0.5


try:
    print(calculate_square_root_input(-9))

except ValueError as error:
    print("Error:", error)

Output:

Error: Number must not be negative.

The raise keyword is useful for enforcing validation rules and making invalid conditions explicit.

10. Creating Custom Exceptions in Python

A custom exception is an exception class created by the programmer to represent a specific application error.

Custom exceptions are useful when built-in exceptions do not clearly describe a business rule or application-specific problem.

Example: Insufficient Balance

class InsufficientBalanceError(Exception):
    pass


def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError("Withdrawal amount must be positive.")

    if amount > balance:
        raise InsufficientBalanceError(
            "Insufficient balance for this withdrawal."
        )

    return balance - amount


try:
    remaining_balance = withdraw(1000, 1500)
    print("Remaining balance:", remaining_balance)

except InsufficientBalanceError as error:
    print("Transaction failed:", error)

Output:

Transaction failed: Insufficient balance for this withdrawal.

The custom InsufficientBalanceError makes it clear why the transaction failed.

Best Practice for Custom Exceptions

Custom exception classes normally inherit from Exception or an appropriate subclass.

Use descriptive names ending in Error when appropriate, and provide useful messages explaining what went wrong.

11. Accessing Exception Messages

You can use as to assign a caught exception to a variable.

try:
    number = int("hello")

except ValueError as error:
    print("Error message:", error)

Output:

Error message: invalid literal for int() with base 10: 'hello'

The exact wording can vary between Python versions.

This approach is useful for logging or displaying an appropriate message. Avoid exposing sensitive internal details to end users.

12. Raising an Exception Again With raise

Sometimes a function needs to perform an action when an exception occurs and then allow the exception to propagate to its caller.

Inside an except block, a bare raise re-raises the currently handled exception while preserving its traceback.

def process_number(value):
    try:
        return int(value)

    except ValueError:
        print("Logging: Invalid numeric input.")
        raise


try:
    process_number("abc")

except ValueError:
    print("The calling code handled the error.")

Output:

Logging: Invalid numeric input.
The calling code handled the error.

Re-raising is useful when an error should be recorded locally but still handled at a higher level.

13. Exception Chaining

Exception chaining preserves the relationship between an original exception and a new exception raised while handling it.

Use raise ... from ... when converting one exception into a more meaningful application-level exception.

class ConfigurationError(Exception):
    pass


def load_port(value):
    try:
        return int(value)

    except ValueError as error:
        raise ConfigurationError(
            "The server port must be an integer."
        ) from error


try:
    load_port("invalid-port")

except ConfigurationError as error:
    print(error)

Output:

The server port must be an integer.

The original ValueError remains available as the cause of the ConfigurationError, helping developers diagnose the problem.

14. Best Practices for Exception Handling

Follow these practices when writing professional Python code:

  1. Catch specific exceptions instead of catching every exception indiscriminately.

  2. Keep try blocks limited to operations that may reasonably fail.

  3. Provide useful error messages.

  4. Use else for code that should run only when the try block succeeds.

  5. Use finally for cleanup that must be attempted as control leaves the structure.

  6. Prefer with for managing files and other supported resources.

  7. Create custom exceptions for meaningful application-specific errors.

  8. Do not silently ignore exceptions.

  9. Use logging when errors need to be recorded for debugging or monitoring.

  10. Avoid displaying internal stack traces or sensitive details to ordinary users.

  11. Validate external input before using it.

  12. Re-raise exceptions when the current function cannot properly resolve the problem.

Avoid a Bare except

Less suitable:

try:
    result = 10 / 0
except:
    print("Something went wrong.")

A bare except can catch exceptions that should usually be allowed to propagate, including interruption-related exceptions.

Better:

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero.")

Specific exception handling is easier to understand and maintain.

15. Practical Project: Simple Banking System

Let's build a small banking example that uses validation and a custom exception.

class InsufficientBalanceError(Exception):
    pass


def deposit(balance, amount):
    if amount <= 0:
        raise ValueError("Deposit amount must be positive.")

    return balance + amount


def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError("Withdrawal amount must be positive.")

    if amount > balance:
        raise InsufficientBalanceError(
            "You do not have enough balance."
        )

    return balance - amount


def main():
    balance = 1000.0

    try:
        print("Opening balance:", balance)

        balance = deposit(balance, 500)
        print("After deposit:", balance)

        balance = withdraw(balance, 300)
        print("After withdrawal:", balance)

    except (ValueError, InsufficientBalanceError) as error:
        print("Transaction error:", error)

    else:
        print("All transactions completed successfully.")

    finally:
        print("Banking operation finished.")


if __name__ == "__main__":
    main()

Output:

Opening balance: 1000.0
After deposit: 1500.0
After withdrawal: 1200.0
All transactions completed successfully.
Banking operation finished.

How This Project Works

  • deposit() validates and adds money to the balance.

  • withdraw() validates the withdrawal and checks the available balance.

  • InsufficientBalanceError represents an application-specific error.

  • try and except handle expected transaction errors.

  • else reports successful completion.

  • finally displays a completion message.

This is an educational example, not a real banking system. Real financial applications require secure authentication, reliable transaction processing, persistent storage, and additional controls.

16. Python Exception Handling Practice Programs

Try these exercises to improve your skills:

  1. Handle division by zero using try and except.

  2. Ask for an integer and handle invalid input.

  3. Handle an IndexError when accessing a list.

  4. Handle a KeyError when looking up a dictionary key.

  5. Read a file and handle FileNotFoundError.

  6. Use else to display a message after a successful calculation.

  7. Use finally to display a cleanup message.

  8. Raise a ValueError when a number is negative.

  9. Create a custom exception for an invalid age.

  10. Create a custom exception for insufficient account balance.

  11. Write a function that catches an exception, logs a message, and re-raises it.

  12. Build a calculator that validates user input and handles invalid operations.

17. Python Exception Handling Interview Questions

Q1. What is an exception in Python?

An exception is an event during execution that interrupts the normal flow of a program.

Q2. What is exception handling?

Exception handling is the process of catching and managing exceptions using constructs such as try and except.

Q3. What is the purpose of the try block?

It contains code that may raise an exception.

Q4. What is the purpose of the except block?

It handles exceptions matching the specified exception type.

Q5. What is the purpose of the else block?

It executes when the try block completes without raising an exception.

Q6. What is the purpose of the finally block?

It runs as control leaves the associated exception-handling structure and is commonly used for cleanup.

Q7. What does the raise keyword do?

It raises an exception deliberately or re-raises a currently handled exception.

Q8. What is a custom exception?

A custom exception is a programmer-defined exception class, usually derived from Exception.

Q9. What is the difference between ValueError and TypeError?

ValueError generally indicates an inappropriate value, while TypeError indicates an inappropriate type for an operation.

Q10. What is ZeroDivisionError?

It is raised when a numeric division operation attempts to divide by zero.

Q11. What does except Exception as error mean?

It catches exceptions derived from Exception and binds the caught exception to the variable error.

Q12. What is exception chaining?

Exception chaining preserves the relationship between an original exception and a new exception, often using raise ... from ....

Conclusion

Exception handling is an essential part of writing reliable Python applications. By understanding try, except, else, finally, raise, built-in exceptions, and custom exceptions, you can manage errors more effectively and make programs easier to maintain.

Practise these concepts with calculators, file-handling programs, and validation tasks before moving on to object-oriented programming.

←
Post 14 of 20
→