ComparisonComparisons

os vs pathlib

os represents paths as plain strings and operates on them with functions, while pathlib represents a path as a Path object with methods and the / operator.

On this page

Side-by-side comparison

#
  • Path representation

    os
    A plain string
    pathlib
    An object of the Path class
  • Joining path parts

    os
    os.path.join(a, b)
    pathlib
    The / operator: a / b
  • File name and extension

    os
    Functions os.path.basename(), os.path.splitext()
    pathlib
    Attributes .name, .stem, .suffix
  • Reading and writing a file

    os
    Through the built-in open()
    pathlib
    Methods .read_text(), .write_text()
  • Environment variables

    os
    os.environ
    pathlib
    None, os is still needed
  • Typical use

    os
    Older code, environment variables
    pathlib
    New code working with paths and files

Example

#
Python
import os
from pathlib import Path

os_path = os.path.join("courses", "python", "lesson_01.py")
path_obj = Path("courses") / "python" / "lesson_01.py"

print(os_path)
print(path_obj)
print(os.path.basename(os_path), path_obj.name)
Resultsaved result, you can check it
courses/python/lesson_01.py
courses/python/lesson_01.py
lesson_01.py lesson_01.py

The result for Linux and macOS. On Windows, both paths would print with backslashes.

Definition and usage

#

Both serve the same tasks: building paths independently of the operating system, checking whether a file exists, and reading a file’s name or extension. Both work correctly on Windows, Linux, and macOS, because they pick the right separator themselves.

They differ in style. In os.path, a path is a plain string, and operations are separate functions that take it and return it: os.path.join(a, b), os.path.basename(path). In pathlib, a path is an object of the Path class, you join its parts with the / operator, and you read its properties as attributes: path.name, path.suffix. File operations, such as reading or writing, are methods on that same object in pathlib, while in os they’re split between os and the built-in open().

pathlib is recommended for new code: it’s more readable and object-oriented, and a single Path variable carries all the operations with it. The os module is still needed for things pathlib doesn’t do, e.g. environment variables (os.environ), and you’ll encounter it in older code.

Syntax

#
Syntax
import os
os.path.join("a", "b.txt")

from pathlib import Path
Path("a") / "b.txt"

More examples

#
Extension and parent directory
Python
from pathlib import Path
import os

path_obj = Path("project") / "notes.md"
os_path = os.path.join("project", "notes.md")

print(path_obj.suffix, path_obj.parent)
print(os.path.splitext(os_path)[1], os.path.dirname(os_path))
Resultsaved result, you can check it
.md project
.md project
Reading and writing a file: open() vs Path methods
Python
import os
from pathlib import Path

notes = Path("notes_pathlib.txt")
notes.write_text("For loop\n", encoding="utf-8")
print(notes.read_text(encoding="utf-8").strip())
notes.unlink()

with open("notes_os.txt", "w", encoding="utf-8") as file:
    file.write("For loop\n")
with open("notes_os.txt", encoding="utf-8") as file:
    print(file.read().strip())
os.remove("notes_os.txt")
Resultsaved result, you can check it
For loop
For loop

Good practices

#
  • Don’t glue paths together with the + operator and hardcoded slashes. os.path.join() or pathlib will insert the separator that’s right for the system.
  • You can pass a Path object directly to open() and to most functions that accept a path. Convert it to a string with str().
  • Keep passwords and API keys in environment variables and read them with os.environ.get(), regardless of whether os or pathlib handles the rest of your paths.

Related entries

#

Spotted a mistake or missing an example? Write to us.