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.
Side-by-side comparison
#Path representation
- os
- A plain string
- pathlib
- An object of the
Pathclass
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,
osis still needed
Typical use
- os
- Older code, environment variables
- pathlib
- New code working with paths and files
Example
#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)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
#import os
os.path.join("a", "b.txt")
from pathlib import Path
Path("a") / "b.txt"More examples
#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))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")Good practices
#- Don’t glue paths together with the
+operator and hardcoded slashes.os.path.join()orpathlibwill insert the separator that’s right for the system. - You can pass a
Pathobject directly toopen()and to most functions that accept a path. Convert it to a string withstr(). - Keep passwords and API keys in environment variables and read them with
os.environ.get(), regardless of whetherosorpathlibhandles the rest of your paths.
Related entries
#Spotted a mistake or missing an example? Write to us.