Python File Handling
Programs save results, read test data and process logs, and all of that means working with files. Python’s built-in open() function plus a with block is all you need for text files.
- Open files safely with with
- Choose the right file mode
- Read a whole file, a line, or all lines
- Write, append and process files line by line
Write a file
open(path, mode) returns a file object. Mode "w" creates the file (or empties it if it exists). The with block closes the file automatically, even if an error happens.
with open("notes.txt", "w", encoding="utf-8") as f: f.write("Python file handling\n") f.write("Line two\n") f.writelines(["Line three\n", "Line four\n"]) print("written")written
Always pass encoding="utf-8" for text files. Without it, Python uses the operating system’s default encoding, which differs between Windows and Linux.
Read a whole file
with open("notes.txt", encoding="utf-8") as f: content = f.read() print(repr(content[:25]))print(len(content.splitlines()), "lines")'Python file handling\nLine' 4 lines
Read line by line
A file object is iterable: a for loop gives one line at a time, which works for files of any size.
with open("notes.txt", encoding="utf-8") as f: for number, line in enumerate(f, start=1): print(number, line.rstrip("\n"))1 Python file handling 2 Line two 3 Line three 4 Line four
readline() reads the next line; readlines() returns a list of all lines (keeping the \n):
with open("notes.txt", encoding="utf-8") as f: first = f.readline() rest = f.readlines() print(repr(first))print(rest)'Python file handling\n' ['Line two\n', 'Line three\n', 'Line four\n']
File modes
| Mode | Meaning | If the file exists | If it does not |
|---|---|---|---|
"r" | read (default) | read from the start | FileNotFoundError |
"w" | write | emptied first | created |
"a" | append | write at the end | created |
"x" | exclusive create | FileExistsError | created |
"r+" | read and write | from the start | FileNotFoundError |
add "b" | binary, e.g. "rb" | bytes instead of str |
Append to a file
with open("notes.txt", "a", encoding="utf-8") as f: f.write("Appended line\n") with open("notes.txt", encoding="utf-8") as f: print(f.read().splitlines()[-2:])['Line four', 'Appended line']
Handle a missing file
with open("does_not_exist.txt", encoding="utf-8") as f: print(f.read())Traceback (most recent call last):
File "main.py", line 1, in <module>
with open("does_not_exist.txt", encoding="utf-8") as f:
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'does_not_exist.txt'Check first, or catch the error:
from pathlib import Path path = Path("does_not_exist.txt")if path.exists(): print(path.read_text(encoding="utf-8"))else: print(f"{path} not found, using defaults") try: open("does_not_exist.txt", encoding="utf-8")except FileNotFoundError as e: print("Caught:", e.strerror)does_not_exist.txt not found, using defaults Caught: No such file or directory
Process a log file
A typical job: read a log, count errors and write a summary.
log = """2026-11-02 09:00 INFO start2026-11-02 09:01 ERROR db timeout2026-11-02 09:02 INFO retry2026-11-02 09:03 ERROR db timeout2026-11-02 09:04 WARN slow response"""with open("app.log", "w", encoding="utf-8") as f: f.write(log) counts = {}errors = []with open("app.log", encoding="utf-8") as f: for line in f: level = line.split()[2] counts[level] = counts.get(level, 0) + 1 if level == "ERROR": errors.append(line.split(maxsplit=3)[3].strip()) with open("summary.txt", "w", encoding="utf-8") as out: for level, n in sorted(counts.items()): out.write(f"{level}: {n}\n") print(open("summary.txt", encoding="utf-8").read().strip())print(set(errors))ERROR: 2
INFO: 2
WARN: 1
{'db timeout'}Read and write several files
with open("notes.txt", encoding="utf-8") as src, open("upper.txt", "w", encoding="utf-8") as dst: for line in src: dst.write(line.upper()) print(open("upper.txt", encoding="utf-8").readline().strip())PYTHON FILE HANDLING
Binary files
Images, PDFs and zip files are binary. Open them with "rb" / "wb" and you get bytes:
data = bytes([137, 80, 78, 71]) # the first bytes of every PNG filewith open("sample.bin", "wb") as f: f.write(data) with open("sample.bin", "rb") as f: head = f.read()print(head, len(head))b'\x89PNG' 4
seek and tell
with open("notes.txt", encoding="utf-8") as f: print(f.read(6)) print(f.tell()) # current position f.seek(0) # back to the start print(f.readline().strip())Python 6 Python file handling
Check your understanding
Predict the output
with open("t.txt", "w") as f: f.write("a\nb\n")with open("t.txt", "w") as f: f.write("c\n")print(open("t.txt").read().split())['c']
The second open in mode "w" empties the file before writing, so only “c” is left. Use "a" to keep the earlier lines.
Quick quiz
1. What does mode “w” do to an existing file?
Use “a” to append, or “x” to refuse to overwrite.
2. Why use with open(...) as f:?
with guarantees clean-up.
3. Which reads one line at a time without loading the whole file?
Iterating over the file object streams it line by line.
Exercise: word statistics
Write a short text to story.txt, then read it back and print the number of lines, words and characters, and the longest word.
"Python reads files easily\nAnd writes them too\n"
2 8 46 Python
Hint 1
Count lines while looping; len(line.split()) counts words.
with open("story.txt", "w", encoding="utf-8") as f: f.write("Python reads files easily\nAnd writes them too\n") lines = words = chars = 0longest = ""with open("story.txt", encoding="utf-8") as f: for line in f: lines += 1 chars += len(line) for word in line.split(): words += 1 if len(word) > len(longest): longest = word print(lines, words, chars, longest)2 8 46 Python
The file is read once, line by line, updating all counters as it goes. chars includes the newline characters, just as the wc command does.
Program Practice
38 Python File Handling Programs
Every program has a step-by-step explanation, colour-coded code and its real output.
Python file handling FAQ
How do I read a file line by line in Python?
with open(path, encoding="utf-8") as f: then for line in f:. Use line.rstrip("\n") to drop the newline.
What is the difference between write() and writelines()?
write() writes one string. writelines() writes every string from a list or other iterable; neither adds newlines for you.
How do I check if a file exists before opening it?
Use os.path.exists(path) or Path(path).exists(), or open it inside try and catch FileNotFoundError.
Do I need to close a file in Python?
Not when you use with, which closes it automatically. Otherwise call f.close() yourself.
2 thoughts on “Python File Handling”