Skip to content

Python · Standard Library Essentials

Python Files & pathlib Explained — Reading, Writing, and Modern Path Handling

3 min read Updated 2026-06-19 Share:

Practice Files, pathlib & os interview questions

Python files & pathlib, explained

Reading and writing files is everyday work, and modern Python makes it clean: context managers guarantee files are closed, and pathlib replaces fragile path-string manipulation with real objects. Here's the idiomatic way to handle both.

Open files with a context manager

Always open files with with. The context manager closes the file automatically — even if an exception is raised mid-read — so you never leak handles or lose buffered writes.

with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()
# file is guaranteed closed here, exception or not

Specify encoding explicitly (almost always "utf-8"); relying on the platform default is a classic source of "works on my machine" text bugs.

File modes and reading patterns

The mode string controls intent: r read, w write (truncates!), a append, x create-or- fail, and a trailing b for binary. There are several ways to read.

with open("data.txt") as f:
    whole = f.read()            # entire file as one string
    # f.readlines() → list of lines

with open("big.log") as f:
    for line in f:              # streams line by line — memory-efficient
        process(line.rstrip("\n"))

Iterating the file object is the right way to handle large files — it never loads everything into memory.

Writing files

w overwrites, a appends. write doesn't add newlines, so include them yourself or use writelines/print(..., file=f).

with open("out.txt", "w", encoding="utf-8") as f:
    f.write("first line\n")
    f.writelines(f"{n}\n" for n in range(3))

with open("out.txt", "a") as f:
    f.write("appended\n")

Be careful: opening with "w" truncates the file the moment it's opened, even before you write anything.

pathlib: paths as objects

pathlib.Path replaces os.path string functions with an object-oriented API. The / operator joins paths portably across operating systems.

from pathlib import Path

p = Path("data") / "reports" / "june.txt"   # OS-correct separator
p.name          # 'june.txt'
p.stem          # 'june'
p.suffix        # '.txt'
p.parent        # Path('data/reports')
p.exists()      # True/False

No more os.path.join, os.path.basename, os.path.splitext — it's all methods and properties on one object.

Reading and writing with Path

Path has convenience methods for the common one-shot read/write, so you don't even need open for simple cases.

from pathlib import Path

p = Path("notes.txt")
p.write_text("hello\n", encoding="utf-8")    # write whole file
text = p.read_text(encoding="utf-8")         # read whole file
data = Path("img.png").read_bytes()          # binary read

For larger or streaming work, p.open() returns a normal file object you use with with.

Globbing and traversing directories

pathlib makes finding and walking files concise. glob matches a pattern in one directory; rglob recurses.

from pathlib import Path

for py in Path("src").rglob("*.py"):     # all .py files, recursively
    print(py)

Path("out").mkdir(parents=True, exist_ok=True)   # create dirs safely
Path("old.txt").unlink(missing_ok=True)          # delete if present

mkdir(parents=True, exist_ok=True) and unlink(missing_ok=True) handle the "already exists / doesn't exist" cases without try/except.

Recap

Open files with with so they're closed automatically, and always pass encoding="utf-8". Know the modes (r/w/a/x, +b), remember w truncates, and iterate the file object to stream large files line by line. Prefer pathlib.Path over os.path: join with /, inspect with .name/.stem/.suffix/.parent, read and write with read_text/write_text/read_bytes, and find files with glob/rglob. It's the modern, portable, readable way to handle the filesystem.

More ways to practice

The self-quiz is live. Get notified when mock interviews and new question packs drop.

or
Join our WhatsApp Channel