Pathlib Module: Modern Path Handling Made Simple
TL;DR
The pathlib module provides object-oriented path handling with the Path class, replacing string-based os.path operations with intuitive methods for cross-platform file and directory manipulation.
Interesting!
Pathlib’s Path objects automatically handle different operating systems’ path separators - you can use the same code on Windows, macOS, and Linux without worrying about forward vs backward slashes.
Creating and Working with Paths
Basic Path Creation
python code snippet start
from pathlib import Path
# Current directory
current = Path.cwd()
print(current) # /Users/username/project
# Home directory
home = Path.home()
print(home) # /Users/username
# Create paths from strings
project_path = Path("my_project")
config_file = Path("config/settings.json")
# Join paths naturally
full_path = project_path / "src" / "main.py"
print(full_path) # my_project/src/main.py
python code snippet end
Path Components and Properties
python code snippet start
path = Path("/Users/alice/documents/report.pdf")
print(path.name) # report.pdf
print(path.stem) # report
print(path.suffix) # .pdf
print(path.parent) # /Users/alice/documents
print(path.parts) # ('/', 'Users', 'alice', 'documents', 'report.pdf')
print(path.is_absolute()) # True
# Change components
new_path = path.with_suffix('.txt')
print(new_path) # /Users/alice/documents/report.txt
python code snippet end
File and Directory Operations
Checking Existence and Types
python code snippet start
path = Path("example.txt")
# Check existence and type
print(path.exists()) # True/False
print(path.is_file()) # True/False
print(path.is_dir()) # True/False
print(path.is_symlink()) # True/False
# Get file info
if path.exists():
print(f"Size: {path.stat().st_size} bytes")
print(f"Modified: {path.stat().st_mtime}")
python code snippet end
Reading and Writing Files
python code snippet start
# Write to file
config = Path("config.txt")
config.write_text("debug=true\nport=8080")
# Read from file
content = config.read_text()
print(content)
# Binary operations
data = b"binary data"
binary_file = Path("data.bin")
binary_file.write_bytes(data)
restored_data = binary_file.read_bytes()
python code snippet end
Directory Operations
python code snippet start
# Create directories
new_dir = Path("project/logs")
new_dir.mkdir(parents=True, exist_ok=True) # Create parent dirs if needed
# List directory contents
project = Path("project")
for item in project.iterdir():
if item.is_file():
print(f"File: {item.name}")
elif item.is_dir():
print(f"Directory: {item.name}")
python code snippet end
Advanced Path Operations
Pattern Matching and Globbing
python code snippet start
# Find all Python files
project = Path("src")
python_files = list(project.glob("*.py"))
print(python_files)
# Recursive search
all_python = list(project.rglob("*.py")) # Search subdirectories too
# Multiple patterns
text_files = list(project.glob("*.{txt,md,rst}"))
# Find files matching pattern
for py_file in project.rglob("test_*.py"):
print(f"Test file: {py_file}")
python code snippet end
Path Resolution and Cleanup
python code snippet start
# Resolve relative paths and symlinks
messy_path = Path("../project/./src/../config/settings.json")
clean_path = messy_path.resolve()
print(clean_path) # /Users/alice/project/config/settings.json
# Relative paths
base = Path("/Users/alice/project")
target = Path("/Users/alice/project/src/main.py")
relative = target.relative_to(base)
print(relative) # src/main.py
python code snippet end
Cross-Platform Compatibility
Working with Different Systems
python code snippet start
# These work the same on Windows, macOS, and Linux
path = Path.home() / "Documents" / "my_file.txt"
# Convert to string for legacy functions
path_string = str(path)
# Convert from string
path_from_string = Path(path_string)
# URL-style paths (useful for web applications)
url_path = path.as_uri()
print(url_path) # file:///Users/alice/Documents/my_file.txt
python code snippet end
Practical Examples
Configuration File Manager
python code snippet start
class ConfigManager:
def __init__(self, app_name):
self.config_dir = Path.home() / f".{app_name}"
self.config_file = self.config_dir / "config.json"
def ensure_config_dir(self):
self.config_dir.mkdir(exist_ok=True)
def load_config(self):
if self.config_file.exists():
return json.loads(self.config_file.read_text())
return {}
def save_config(self, config_data):
self.ensure_config_dir()
self.config_file.write_text(json.dumps(config_data, indent=2))
python code snippet end
Project File Organizer
python code snippet start
def organize_downloads():
downloads = Path.home() / "Downloads"
# Create organized folders
for folder in ["images", "documents", "archives"]:
(downloads / folder).mkdir(exist_ok=True)
# Organize files by extension
for file_path in downloads.iterdir():
if file_path.is_file():
if file_path.suffix.lower() in ['.jpg', '.png', '.gif']:
file_path.rename(downloads / "images" / file_path.name)
elif file_path.suffix.lower() in ['.pdf', '.docx', '.txt']:
file_path.rename(downloads / "documents" / file_path.name)
elif file_path.suffix.lower() in ['.zip', '.tar', '.gz']:
file_path.rename(downloads / "archives" / file_path.name)
python code snippet end
Backup Utility
python code snippet start
def backup_project(source_dir, backup_dir):
source = Path(source_dir)
backup = Path(backup_dir)
if not source.exists():
raise ValueError(f"Source directory {source} does not exist")
# Create timestamped backup folder
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_path = backup / f"backup_{timestamp}"
backup_path.mkdir(parents=True)
# Copy all files
for file_path in source.rglob("*"):
if file_path.is_file():
relative_path = file_path.relative_to(source)
dest_path = backup_path / relative_path
dest_path.parent.mkdir(parents=True, exist_ok=True)
dest_path.write_bytes(file_path.read_bytes())
print(f"Backup created at {backup_path}")
python code snippet end
When to Use Pathlib vs os.path
Use Pathlib When:
- Building new applications
- Need object-oriented interface
- Want cross-platform compatibility
- Working with modern Python (3.4+)
Use os.path When:
- Working with legacy codebases
- Need maximum backward compatibility
- Interfacing with older libraries
The pathlib module represents the modern, Pythonic way to handle file paths, making code more readable, maintainable, and cross-platform compatible.
Pathlib works beautifully with JSON file operations for configuration management and data storage tasks. For more advanced file operations, see input/output handling and module organization for project structure management.
Reference: Python Pathlib Module Documentation