Files I/O, Exceptions and Modules
File handling, exception handling, and modules are three very important parts of Python.
Almost every real project uses them. File handling lets you save and read data. Exceptions let you deal with errors without crashing your program. Modules let you split your code into smaller, reusable pieces.
Files in Python
Section titled “Files in Python”Files let you save data so it sticks around even after your program stops running. When your program ends, everything stored in variables disappears - but files stay saved on your computer’s disk. Python can work with many types of files like text files, binary files, CSV files, logs, and more.
The basic steps for working with files are:
- Open the file
- Do something with it (read or write)
- Close the file
File Modes
Section titled “File Modes”| Mode | Meaning |
|---|---|
r | Read file (must exist) |
w | Write (overwrite file) |
a | Append (add at end) |
x | Create new file |
b | Binary mode |
t | Text mode |
+ | Read and write |
Opening Files
Section titled “Opening Files”You can open a file using open() and close it manually when you’re done.
file = open("notes.txt", "r", encoding="utf-8")content = file.read()print(content)file.close()Explanation:
open()opens the fileread()reads contentclose()releases the file
Problem:
If something goes wrong before close() runs, the file stays open. This can cause bugs or waste memory.
Using with
Section titled “Using with”The with statement handles closing the file for you automatically, even if an error happens in the middle.
with open("notes.txt", "r", encoding="utf-8") as file: content = file.read() print(content)Why use with:
- Automatically closes the file when you’re done
- Safer and cleaner to write
- No risk of accidentally leaving files open
Reading Files
Section titled “Reading Files”Reading means pulling data out of a file and into your program.
Read full file
Section titled “Read full file”with open("notes.txt", "r", encoding="utf-8") as file: content = file.read()Read line by line
Section titled “Read line by line”with open("notes.txt", "r", encoding="utf-8") as file: for line in file: print(line.strip())Reading line by line is better for large files because it doesn’t load everything into memory at once.
Writing and Appending
Section titled “Writing and Appending”Writing replaces everything already in the file. Appending adds new content to the end without touching what’s already there.
# Writewith open("notes.txt", "w", encoding="utf-8") as file: file.write("First line\n")
# Appendwith open("notes.txt", "a", encoding="utf-8") as file: file.write("Second line\n")Binary Files
Section titled “Binary Files”Binary files store raw data as bytes, not as readable text. You use these for things like images, videos, and PDFs.
Writing binary file
Section titled “Writing binary file”data = b"Hello"
with open("data.bin", "wb") as file: file.write(data)Reading binary file
Section titled “Reading binary file”with open("data.bin", "rb") as file: content = file.read() print(content)Object Files
Section titled “Object Files”Sometimes you want to save a whole Python object - like a list or a dictionary - directly into a file and load it back later. This is called serialization.
Using pickle
Section titled “Using pickle”import pickle
data = {"name": "Sahil", "age": 21}
# Save objectwith open("data.pkl", "wb") as file: pickle.dump(data, file)
# Load objectwith open("data.pkl", "rb") as file: loaded = pickle.load(file) print(loaded)Explanation:
dump()-> saves the object to the fileload()-> reads the object back from the file
Using pathlib
Section titled “Using pathlib”pathlib is a modern and cleaner way to work with file paths in Python. It’s easier to use than dealing with raw strings, and it works correctly on all operating systems (Windows, Mac, Linux).
from pathlib import Path
path = Path("data") / "notes.txt"print(path)The / operator here is not division - it’s used to join parts of a path together.
Exceptions in Python
Section titled “Exceptions in Python”Exceptions are errors that happen while your program is running. Instead of just crashing and stopping, Python lets you catch these errors and handle them gracefully.
Common Exceptions
Section titled “Common Exceptions”| Exception | Meaning |
|---|---|
| FileNotFoundError | File not found |
| ZeroDivisionError | Division by zero |
| ValueError | Invalid value |
| TypeError | Wrong type |
| IndexError | Invalid index |
| KeyError | Missing key |
try / except / else / finally
Section titled “try / except / else / finally”try: number = int("42")except ValueError: print("Invalid number")else: print("Success:", number)finally: print("Always runs")Explanation:
try-> put the code here that might go wrongexcept-> this runs if an error happenselse-> this runs only if no error happenedfinally-> this always runs no matter what
Raising Exceptions
Section titled “Raising Exceptions”You can trigger an error yourself when something in your code doesn’t make sense.
def set_age(age): if age < 0: raise ValueError("Age cannot be negative") return ageCustom Exceptions
Section titled “Custom Exceptions”You can create your own error types to make your program easier to understand and debug.
class InvalidAmountError(Exception): pass
def withdraw(balance, amount): if amount > balance: raise InvalidAmountError("Not enough balance") return balance - amountUsing a custom exception like InvalidAmountError is much clearer than a plain Exception - anyone reading the code immediately knows what went wrong.
Modules in Python
Section titled “Modules in Python”A module is just a Python file that holds code you want to reuse. Instead of writing the same functions over and over in every file, you put them in a module and import them wherever you need them.
Import Styles
Section titled “Import Styles”import mathimport math as mfrom math import sqrtfrom math import sqrt as square_rootCreating Your Own Module
Section titled “Creating Your Own Module”helpers.py
def clean_text(text): return text.strip().lower()main.py
from helpers import clean_text
print(clean_text(" Hello "))__name__ == __main__
Section titled “__name__ == __main__”This trick lets a file work both as a runnable script and as a module that other files can import.
def main(): print("Running directly")
if __name__ == "__main__": main()The code inside the if block only runs when you run this file directly. If another file imports it, that block is skipped.
Import Flow
Section titled “Import Flow”Packages in Python
Section titled “Packages in Python”A package is a folder that holds multiple modules. When your project gets big, packages help you keep things organized.
Example structure:
project/│├── main.py├── utils/│ ├── __init__.py│ ├── helpers.py│ └── parser.pyImporting from Packages
Section titled “Importing from Packages”from utils.helpers import clean_textRelative Imports (., ..)
Section titled “Relative Imports (., ..)”Relative imports are used inside packages to import from other files based on where the current file is located - instead of spelling out the full path.
Current directory (.)
Section titled “Current directory (.)”from .helpers import clean_textThis means: import clean_text from helpers.py in the same folder as this file.
Parent directory (..)
Section titled “Parent directory (..)”from ..config import settingsThis means: go one folder up, then import settings from config.py.
Understanding with structure
Section titled “Understanding with structure”project/│├── app/│ ├── main.py│ └── utils/│ └── helper.pyInside helper.py:
from ..main import somethingExplanation:
..-> go up one folder toapp/- then import
somethingfrommain.pyinsideapp/
Absolute vs Relative Imports
Section titled “Absolute vs Relative Imports”| Type | Example | Meaning |
|---|---|---|
| Absolute | from utils.helpers import clean_text | Full path from the project root |
| Relative | from .helpers import clean_text | Path based on where the current file is |
Absolute imports are easier to read and understand at a glance. Relative imports are handy when working inside a package and you want to refer to nearby files without writing the full path.