Working with files is one of the most common things we do in Python. Read some data, process it, write the result. Let’s see how it all works.
Opening Files
The open() function is our gateway to files. It returns a file object that we can read from or write to.
f = open("notes.txt", "r") # open for reading (default mode)
content = f.read()
f.close() # always close when done!
But we should never do it that way. If an error happens before close(), the file stays open and we leak resources.
The with Statement
This is the right way. The with block automatically closes the file when we’re done — even if an error occurs.
with open("notes.txt", "r") as f:
content = f.read()
# file is automatically closed here
File Modes
"r"— read (default, file must exist)"w"— write (creates file or overwrites existing content)"a"— append (adds to the end)"rb"/"wb"— read/write in binary mode (for images, PDFs, etc.)"r+"— read and write
Reading Files
We have several options depending on what we need.
with open("data.txt", "r", encoding="utf-8") as f:
whole_thing = f.read() # entire file as one string
# or
one_line = f.readline() # next line
# or
all_lines = f.readlines() # list of all lines
# best for large files — reads one line at a time
for line in f:
print(line.strip()) # strip() removes trailing newline
Always pass encoding="utf-8" explicitly. The default encoding varies by OS, and that leads to nasty bugs.
Writing Files
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, world!\n") # write a string
f.writelines(["line 1\n", "line 2\n"]) # write a list of strings
Remember: "w" mode wipes the file clean first. Use "a" to add to the end without erasing.
Modern File Paths with pathlib
The pathlib module gives us an object-oriented way to work with file paths. It’s cleaner than string concatenation and works across operating systems.
from pathlib import Path
p = Path("data") / "reports" / "sales.csv" # builds path with /
print(p.exists()) # True/False
print(p.suffix) # .csv
print(p.stem) # sales
content = p.read_text(encoding="utf-8") # read in one shot
p.write_text("new content", encoding="utf-8") # write in one shot
Working with JSON
Python’s json module makes it easy to read and write JSON files.
import json
# Writing JSON
data = {"name": "Manish", "age": 25, "skills": ["Python", "JS"]}
with open("data.json", "w") as f:
json.dump(data, f, indent=2) # indent for pretty printing
# Reading JSON
with open("data.json", "r") as f:
loaded = json.load(f) # returns a dict
Working with CSV
import csv
# Reading CSV
with open("people.csv", "r") as f:
reader = csv.reader(f)
header = next(reader) # grab the header row
for row in reader:
print(row) # each row is a list of strings
# Writing CSV
with open("output.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["name", "age"])
writer.writerow(["Manish", 25])
In simple language, with open(...) is the pattern we use 99% of the time. Pick the right mode, don’t forget encoding, and let the with block handle cleanup.