File Handling
Reading and writing files from Python — plain text, structured binary data, and spreadsheet-style CSV.
Basics (Opening & Closing, File Modes)
Files are opened with open(filename, mode), which gives you back a file object to read or write through. The mode tells Python what you intend to do:
"r"— read (the default); raisesFileNotFoundErrorif the file doesn't exist"w"— write; creates the file if needed, and erases any existing content first"a"— append; creates the file if needed, and adds new content after whatever's already there
f = open("notes.txt", "r")
data = f.read()
f.close()
print(data)
Closing a file with close() matters — Python buffers what you write and doesn't always save it to disk immediately, so forgetting to close a file can mean losing data.
With Clause
with open(...) as f: closes the file automatically once the block finishes — even if an error happens partway through — so you don't have to remember to call close() yourself.
with open("notes.txt", "r") as f:
data = f.read()
print(data)
This is the recommended way to work with files for exactly that reason: it's safer, and one line shorter.
Text Files
For reading, read() grabs the whole file as one string, readline() grabs just the next line, and readlines() returns every line as a list of strings.
with open("notes.txt", "r") as f:
print(f.readlines())
For writing, write() writes a single string, and writelines() writes a list of strings all at once. Remember that "w" mode erases the file first — use "a" if you want to add on to what's already there instead.
with open("notes.txt", "w") as f:
f.write("First line\n")
f.write("Second line\n")
File Pointers
Every open file has a pointer marking where the next read or write will happen. tell() reports its current position, and seek(offset) moves it.
with open("notes.txt", "r") as f:
f.read(5)
print(f.tell())
f.seek(0)
print(f.read(5))
Binary Files & Pickle
Binary files store raw bytes instead of text, so the regular read()/write() functions don't work on Python objects directly. The pickle module bridges that gap — it serializes objects like lists and dictionaries into bytes to write, and deserializes them back when reading. File modes need a "b", e.g. "wb" or "rb".
import pickle
data = ["ByteWise", "on", "top"]
with open("data.dat", "wb") as f:
pickle.dump(data, f)
import pickle
with open("data.dat", "rb") as f:
loaded = pickle.load(f)
print(loaded)
Trying to load() past the last object saved raises an EOFError, so files with multiple saved objects are usually read in a loop wrapped in a try/except.
CSV Files
CSV (Comma-Separated Values) files store tabular data as plain text, with a comma separating each field by default. The csv module provides a writer and a reader object to handle the formatting for you.
import csv
with open("people.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Name", "Age"])
writer.writerow(["ByteWise", 5])
import csv
with open("people.csv", "r") as f:
reader = csv.reader(f)
for row in reader:
print(row)
Notice everything comes back as a string, even the age — convert it with int() or float() if you need to do math with it.