A file is a named location stored on a non-volatile secondary storage medium (such as an SSD or Hard Disk) that stores a sequence of related bytes or characters for future retrieval.
File Handling refers to the mechanism by which a Python program interacts with the host operating system to create, open, read, modify, append, and close files on disk storage.
| Feature | Text Files (.txt, .csv, .json, .py) |
Binary Files (.png, .mp3, .pdf, .exe) |
|---|---|---|
| Encoding | Sequence of human-readable characters encoded in UTF-8 or ASCII. | Raw stream of bytes (0s and 1s) without character encoding. |
| Line Terminators | Has end-of-line characters (\n or \r\n). |
No line delimiters; continuous byte stream. |
| Readability | Can be opened and edited in Notepad or VS Code directly. | Shows gibberish/corrupted symbols if opened in a text editor. |
| Python Mode | "r", "w", "a" |
"rb", "wb", "ab" |
In Python, you interact with files using the built-in open() function. It requests the operating system to allocate a file descriptor (file handle) and returns a file stream object:
file_object = open(file_name, access_mode, encoding="utf-8")
file_name: A string representing the relative path (e.g. "data.txt") or absolute path (e.g. "C:/reports/data.txt") of the target file.access_mode: A string specifying what operations you want to perform (read, write, append). Defaults to "r" (read) if omitted.encoding: The character encoding standard. Always specify encoding="utf-8" in modern Python to ensure international text and symbols work identically on Windows, Mac, and Linux.Every time you open a file, the operating system dedicates system resources (file locks, memory buffers). Calling file.close() is mandatory for three reasons:
close(), your written text might never reach the disk and is lost forever!OSError: Too many open files.# Step 1: Open file in write mode ('w')
file_handle = open("sample_demo.txt", "w", encoding="utf-8")
# Step 2: Write text data to the file
file_handle.write("DevAscent Academy - Unit 10 File Handling\n")
file_handle.write("Learning Python persistent storage step by step!\n")
# Step 3: Explicitly close the file to flush buffer to disk
file_handle.close()
print("File written and closed successfully!")
print("Is the file closed?:", file_handle.closed)
'r' (Read Mode)'a' (Append Mode)'w' (Write Mode)'x' (Exclusive Mode)| Mode | Name | If File Already Exists? | If File Does NOT Exist? | Initial File Pointer Position |
|---|---|---|---|---|
"r" |
Read | Opens file for reading. | Raises FileNotFoundError | Beginning of file (Index 0) |
"w" |
Write | OVERWRITES (Truncates to 0 bytes!) | Creates a brand new file | Beginning of file (Index 0) |
"a" |
Append | PRESERVES existing content | Creates a brand new file | End of file (EOF) |
"x" |
Exclusive | Raises FileExistsError | Creates a brand new file | Beginning of file (Index 0) |
"r+" |
Read + Write | Opens for both reading and writing. | Raises FileNotFoundError | Beginning of file (Index 0) |
"w+" |
Write + Read | Overwrites and allows reading. | Creates a brand new file | Beginning of file (Index 0) |
# 1. Overwriting with 'w'
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Line 1: Initial content.\n")
# 2. Appending with 'a' (adds to end without destroying Line 1)
with open("notes.txt", "a", encoding="utf-8") as f:
f.write("Line 2: Appended message.\n")
# 3. Reading back with 'r'
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
print("Current contents of notes.txt:")
print(content)
# 4. Exclusive creation with 'x' (catches existing file safely)
try:
with open("notes.txt", "x", encoding="utf-8") as f:
f.write("This will fail because notes.txt already exists!")
except FileExistsError:
print("Safe Catch: notes.txt already exists, 'x' mode prevented accidental overwrite!")
\n. Ideal for line-by-line processing.['Line 1\n', 'Line 2\n'].# Setup dummy file for demonstration
with open("students.txt", "w", encoding="utf-8") as f:
f.write("101,Rahul Sharma,BCA\n102,Pooja Verma,B.Tech\n103,Amit Kumar,BCA\n")
# Method 1: read() -> Entire file as a single string
with open("students.txt", "r", encoding="utf-8") as f:
full_text = f.read()
print("--- 1. read() Output (Single String) ---")
print(full_text)
# Method 2: readlines() -> List of string lines
with open("students.txt", "r", encoding="utf-8") as f:
lines_list = f.readlines()
print("--- 2. readlines() Output (List) ---")
print(lines_list)
# Method 3: BEST PRACTICE for Big Files -> Direct Loop Iteration
print("\n--- 3. Best Practice: Memory-Efficient for-loop ---")
with open("students.txt", "r", encoding="utf-8") as f:
for line_no, line in enumerate(f, start=1):
clean_line = line.strip() # removes trailing newline '\n'
print(f"Line {line_no}: {clean_line}")
In older Python tutorials, programmers wrote f = open(...) and f.close(). However, if an error occurred in the middle (e.g. ZeroDivisionError, ValueError), the program would crash before reaching f.close(), leaving the file locked in RAM forever!
The with statement introduces a Context Manager (implementing the __enter__ and __exit__ protocol). It guarantees that the file is closed automatically the exact moment execution leaves the indented block, even if an unhandled exception or crash happens!
with open('file.txt', 'r') as f: runs __enter__. File is safely opened.__exit__. File is closed automatically! No leaks, even on crash.# Demonstrating automatic closure after the with block
with open("autoclose_test.txt", "w", encoding="utf-8") as file:
file.write("Testing automatic closure!\n")
print("Inside the 'with' block: Is file closed? ->", file.closed)
# Notice we are now OUTSIDE the with block (unindented)
print("Outside the 'with' block: Is file closed? ->", file.closed)
CSV (Comma-Separated Values) is a plain text tabular data format where each line represents a data record, and each field within that record is separated by a delimiter (typically a comma ,). It is the universal standard for exporting tables between Python, Microsoft Excel, and SQL databases.
Python provides the dedicated built-in csv module to handle row parsing, commas inside quoted text, and header mapping automatically.
import csv
# --- 1. Writing to a CSV File using csv.writer ---
student_records = [
["Roll No", "Name", "Marks", "City"],
[101, "Aman Gupta", 88, "Delhi"],
[102, "Neha Sharma", 92, "Jaipur"],
[103, "Karan Joshi", 76, "Mumbai"]
]
# newline='' prevents blank lines on Windows systems
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(student_records)
print("CSV File written successfully!")
# --- 2. Reading a CSV File using csv.DictReader (Header-aware!) ---
print("\nReading CSV using csv.DictReader:")
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f" Student #{row['Roll No']} -> {row['Name']} ({row['City']}) Scored: {row['Marks']}")
JSON (JavaScript Object Notation) is a lightweight, human-readable data interchange format. It is the de facto global standard for communication between mobile apps, web servers, and cloud REST APIs. JSON maps directly to Python's built-in data types (Python Dictionaries ➔ JSON Objects, Python Lists ➔ JSON Arrays, Booleans ➔ true/false).
{"user": "Admin", "id": 101}config.json| Operation | File Method (Disk) | String Method (In-Memory) | Conversion Direction |
|---|---|---|---|
| Serialization (Encoding) | json.dump(obj, file) |
json.dumps(obj) |
Python Dict / List ➔ JSON format |
| Deserialization (Decoding) | json.load(file) |
json.loads(string) |
JSON format ➔ Python Dict / List |
import json
# Python Dictionary with nested structure
college_profile = {
"institution": "DevAscent Academy",
"established": 2024,
"active": True,
"courses": ["Python for Systems", "Data Structures", "Web Dev"],
"contact": {
"email": "support@devascentacademy.me",
"city": "New Delhi"
}
}
# 1. Serialization: Saving Python dict to 'profile.json' with indent=4
with open("profile.json", "w", encoding="utf-8") as f:
json.dump(college_profile, f, indent=4)
print("JSON file saved successfully!")
# 2. Deserialization: Reading JSON file back into Python dictionary
with open("profile.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print("\nDeserialized Python Data Type:", type(loaded_data).__name__)
print(f"Institution : {loaded_data['institution']}")
print(f"City : {loaded_data['contact']['city']}")
print(f"Courses (3) : {', '.join(loaded_data['courses'])}")
This capstone combines all elements from Unit 10: appending operational logs to a text file with mode="a", saving structured student rosters to CSV, and loading system settings from JSON.
import csv
import json
import datetime
def log_system_event(action_message):
"""Appends a timestamped audit log to a text file."""
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("audit_log.txt", "a", encoding="utf-8") as log_file:
log_file.write(f"[{timestamp}] {action_message}\n")
def save_roster_csv(filename, students):
"""Exports student records to CSV format."""
fieldnames = ["id", "name", "course", "gpa"]
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(students)
log_system_event(f"Exported {len(students)} student records to {filename}")
# Execute Workflow
student_roster = [
{"id": 101, "name": "Ananya Roy", "course": "BCA 1st Year", "gpa": 8.9},
{"id": 102, "name": "Siddharth Rao", "course": "B.Tech CSE", "gpa": 9.2},
{"id": 103, "name": "Kavita Sen", "course": "BCA 1st Year", "gpa": 7.8}
]
save_roster_csv("roster_2026.csv", student_roster)
print("=== AUDIT LOG CONTENTS ===")
with open("audit_log.txt", "r", encoding="utf-8") as f:
print(f.read().strip())
print("\n=== GENERATED CSV PREVIEW ===")
with open("roster_2026.csv", "r", encoding="utf-8") as f:
print(f.read().strip())
with open() statement employs a Context Manager that guarantees the file is automatically closed as soon as the block terminates, even if an unexpected exception or crash occurs. Manual closing can easily be skipped if an error occurs midway, leading to memory leaks and file lock errors.
read([n]): Reads the entire file (or up to $n$ bytes) into a single string.readline(): Reads a single line (up to newline \n) as a string.readlines(): Reads all remaining lines into a list of strings.
'x' stands for Exclusive Creation. It creates and opens a new file for writing, but if the file already exists on the disk, it immediately raises a FileExistsError to prevent accidental file corruption or overwrite.
json.dump(obj, file_handle): Serializes a Python object directly to an open file on disk.json.dumps(obj): Serializes a Python object into an in-memory JSON formatted string.
cp1252, while Linux uses utf-8). Specifying encoding="utf-8" ensures your Python programs can read and write international characters, emojis, and symbols consistently across all operating systems without throwing UnicodeDecodeError.