pathlib.Path

Path is PurePath plus I/O. Build it from strings, join with /, then ask it questions (exists, is_file) or act on it (read_text, mkdir, glob). Relative paths are resolved against the current working directory at the moment you use them.

pathlib classPython 3.4+Live demo
Common call
Path('data') / 'raw' / 'sales.csv'
Returns
PosixPath or WindowsPath — str() is native, as_posix() uses /
Replaces
os.path.join + open + os.listdir + os.makedirs …
Watch out
Relative paths depend on the cwd, not on the script location
pathlib.Path(*pathsegments)
→ PosixPath | WindowsPath

Demo

Live evaluation
The / operator adds one segment. An absolute segment starts over from the root.
Try:
Inputs
basestrstarting path
childstrsegment to add
Code
from pathlib import Path
(Path('data') / 'raw/sales.csv').as_posix()
Result
'data/raw/sales.csv'

The join tab shows as_posix() so the result reads the same on every OS; str() would show backslashes on Windows. "data/" and "data" join identically because the trailing slash is dropped when the path is parsed, and an absolute child like "/etc/hosts" discards the base completely.

Parameters

NameTypeRequiredDescription
*pathsegmentsstr | os.PathLikeno ('.')Joined like os.path.join. Path() with no arguments is the current directory, ".".

Return value

PosixPath | WindowsPath — Path itself is a factory: you get the concrete class for the running OS.

Common patterns

Anchor paths to the script, not the cwd
Relative paths follow the current directory of the process; __file__ does not.
from pathlib import Path
DATA = Path(__file__).resolve().parent / 'data'
Accept str or Path in your own functions
Path(x) is a no-op copy for Path input and parses strings.
from pathlib import Path
def word_count(path):
    return len(Path(path).read_text(encoding='utf-8').split())
Pass a Path to any API that wants a filename
open(), shutil, json, csv and os all take os.PathLike objects.
import shutil
from pathlib import Path
src = Path('report.pdf')
shutil.copy(src, Path('backup') / src.name)
Home and current directory
Class methods that return absolute paths.
from pathlib import Path
home = Path.home()
here = Path.cwd()

Examples

1. Path is PurePath plus I/O
from pathlib import Path, PurePath isinstance(Path('x'), PurePath)
Returns
True
2. You get the OS-specific class
import os from pathlib import Path type(Path('x')).__name__ == ('WindowsPath' if os.name == 'nt' else 'PosixPath')
Returns
True
3. Chain / to build a path
from pathlib import Path (Path('project') / 'src' / 'main.py').as_posix()
Returns
'project/src/main.py'
4. A str on the left works too
from pathlib import Path ('logs' / Path('app.log')).as_posix()
Returns
'logs/app.log'
5. Write and inspect a file
from pathlib import Path p = Path('todo.txt') p.write_text('ship it', encoding='utf-8') (p.exists(), p.is_file(), p.stat().st_size)
Returns
(True, True, 7)
6. open() accepts a Path
from pathlib import Path p = Path('data.txt') p.write_text('42', encoding='utf-8') with open(p, encoding='utf-8') as f: value = int(f.read()) value
Returns
42
7. cwd() is absolute
from pathlib import Path Path.cwd().is_absolute()
Returns
True

Pitfalls

1. Showing str(path) and expecting forward slashes
str() is the native form, so the same code prints 'a/b' on Linux and 'a\b' on Windows. Use as_posix() for logs, URLs and cross-platform output.
native str()
import os
from pathlib import Path
str(Path('a') / 'b') == ('a\\b' if os.name == 'nt' else 'a/b')
True
as_posix()
from pathlib import Path
(Path('a') / 'b').as_posix()
'a/b'
2. Adding strings to a Path with +
Paths do not support +. Use / for a new segment, or with_name / with_suffix to change the last one. (Shown with PurePosixPath so the class name in the message is the same on every OS; Path gives PosixPath or WindowsPath there.)
path + str
from pathlib import PurePosixPath
PurePosixPath('report') + '.pdf'
TypeError: unsupported operand type(s) for +: 'PurePosixPath' and 'str'
with_suffix
from pathlib import PurePosixPath
PurePosixPath('report').with_suffix('.pdf')
PurePosixPath('report.pdf')
3. Instantiating the other OS class
WindowsPath cannot be created on Linux, nor PosixPath on Windows. Use the pure classes for foreign paths.
foreign concrete class
import os
from pathlib import PosixPath, WindowsPath
foreign = PosixPath if os.name == 'nt' else WindowsPath
try:
    foreign('x')
except Exception as e:
    result = type(e).__name__
result
'UnsupportedOperation'
pure flavour
from pathlib import PurePosixPath, PureWindowsPath
(PurePosixPath('x'), PureWindowsPath('x'))
(PurePosixPath('x'), PureWindowsPath('x'))

When to use

Use it
  • Every file-system path in new code
  • Small whole-file reads and writes (read_text / write_bytes …)
  • Listing and searching directories (iterdir, glob, rglob, walk)
Reach for something else
  • Paths that are not on this machine → PurePosixPath / PureWindowsPath
  • Recursive copy / delete → shutil.copytree / shutil.rmtree

Notes

CPython impl
Lib/pathlib/_local.py: Path.__new__ returns WindowsPath if os.name == "nt" else PosixPath; I/O methods call os.* (os.stat, os.scandir, os.mkdir …) with the path
os.PathLike
Every PurePath implements __fspath__, so any function taking a filename accepts it
Relative paths
Interpreted against os.getcwd() at call time — changing directory changes what a relative Path refers to
Immutability
Paths are immutable and hashable: methods such as with_suffix and / return new objects

FAQ

PurePath only works with the path text; Path adds methods that touch the file system (exists, read_text, mkdir, glob, stat …). Path is a subclass of PurePath, so it also has every pure method.