Python Path Handling: os.path, pathlib, glob, and shutil Overview
This article provides a comprehensive guide to Python's path manipulation tools, covering the os.path module functions, the object‑oriented pathlib API, file‑matching with glob, and advanced file operations using shutil, complete with code examples and usage recommendations.
Path manipulation is a common task in Python, and the language offers several built‑in libraries that simplify cross‑platform file and directory handling.
os.path provides basic functions for joining paths, checking existence, determining file or directory types, and extracting components. Common functions include os.path.join , os.path.exists , os.path.isdir , os.path.isfile , os.path.basename , os.path.dirname , os.path.split , os.path.splitext , os.path.abspath , and os.path.relpath .
import os
joined_path = os.path.join("folder", "subfolder", "file.txt")
print(joined_path) # folder/subfolder/file.txt (Linux/macOS) or folder\subfolder\file.txt (Windows) path_to_check = "/etc/passwd"
if os.path.exists(path_to_check):
print(f"{path_to_check} exists")
else:
print(f"{path_to_check} does not exist") directory_path = "/usr/local/bin"
if os.path.isdir(directory_path):
print(f"{directory_path} is a directory")
else:
print(f"{directory_path} is not a directory") file_path = "/etc/passwd"
if os.path.isfile(file_path):
print(f"{file_path} is a file")
else:
print(f"{file_path} is not a file") full_path = "/home/user/documents/report.txt"
base_name = os.path.basename(full_path)
print(base_name) # report.txt dir_name = os.path.dirname(full_path)
print(dir_name) # /home/user/documents head, tail = os.path.split(full_path)
print(f"head: {head}, tail: {tail}") # head: /home/user/documents, tail: report.txt filename, extension = os.path.splitext(full_path)
print(f"filename: {filename}, extension: {extension}") # filename: /home/user/documents/report, extension: .txt relative_path = "documents/report.txt"
absolute_path = os.path.abspath(relative_path)
print(absolute_path) # absolute path of the file target_path = "/home/user/documents/report.txt"
start_path = "/home/user"
relative_path = os.path.relpath(target_path, start=start_path)
print(relative_path) # documents/report.txtpathlib offers an object‑oriented approach to file system paths, improving readability and maintainability. Key class Path provides methods such as exists() , is_dir() , is_file() , parent , name , suffix , with_name() , with_suffix() , iterdir() , mkdir() , unlink() , and resolve() .
from pathlib import Path
current_dir = Path('.')
print(current_dir) # .
file_path = Path('/home/user/documents/report.txt')
print(file_path) # /home/user/documents/report.txt file_path = Path('/etc/passwd')
if file_path.exists():
print(f"{file_path} exists")
else:
print(f"{file_path} does not exist") directory_path = Path('/usr/local/bin')
if directory_path.is_dir():
print(f"{directory_path} is a directory")
file_path = Path('/etc/passwd')
if file_path.is_file():
print(f"{file_path} is a file") parent_directory = file_path.parent
print(parent_directory) # /home/user/documents file_name = file_path.name
print(file_name) # report.txt extension = file_path.suffix
print(extension) # .txt new_file_path = file_path.with_name('summary.txt')
print(new_file_path) # /home/user/documents/summary.txt new_file_path = file_path.with_suffix('.md')
print(new_file_path) # /home/user/documents/report.md for entry in Path('/home/user/documents').iterdir():
print(entry) # each file or subdirectory new_directory = Path('./new_folder')
new_directory.mkdir(exist_ok=True) file_to_delete = Path('./old_file.txt')
if file_to_delete.exists():
file_to_delete.unlink() relative_path = Path('documents/report.txt')
absolute_resolved_path = relative_path.resolve()
print(absolute_resolved_path) # absolute resolved pathglob simplifies file searching with pattern matching. The primary functions are glob.glob (returns a list) and glob.iglob (returns an iterator). Wildcards such as * , ? , [seq] , and [!seq] are supported.
import glob
txt_files = glob.glob('*.txt')
print(txt_files) # list of .txt files in current directory
py_files_recursive = glob.glob('src/**/*.py', recursive=True)
print(py_files_recursive) # all .py files under src for txt_file in glob.iglob('*.txt'):
print(txt_file)
for py_file in glob.iglob('src/**/*.py', recursive=True):
print(py_file) csv_files = glob.glob('data*.csv')
print(csv_files)
ab_files = glob.glob('?a*.txt') + glob.glob('?b*.txt')
print(ab_files)
numbered_files = glob.glob('*[0-9]*')
print(numbered_files) from pathlib import Path
import glob
absolute_txt_paths = [Path(p).resolve() for p in glob.glob('*.txt')]
print(absolute_txt_paths)
py_parent_dirs = set(Path(p).parent for p in glob.glob('**/*.py', recursive=True))
print(py_parent_dirs) import glob, os
non_empty_txt_files = [f for f in glob.glob('*.txt') if os.path.getsize(f) > 0]
print(non_empty_txt_files)
import time
one_week_ago = time.time() - 7*24*60*60
recent_py_files = [f for f in glob.glob('**/*.py', recursive=True) if os.path.getmtime(f) > one_week_ago]
print(recent_py_files)shutil focuses on higher‑level file operations such as copying, moving, and deleting files or entire directory trees, as well as creating archives and checking disk usage. Frequently used functions include shutil.copy , shutil.copytree , shutil.rmtree , shutil.move , shutil.make_archive , shutil.unpack_archive , and shutil.disk_usage .
import shutil, os
source_file = 'example.txt'
destination_file = 'backup/example.txt'
os.makedirs(os.path.dirname(destination_file), exist_ok=True)
shutil.copy(source_file, destination_file)
print(f"File copied to {destination_file}") source_directory = 'my_project'
destination_directory = 'my_project_backup'
shutil.copytree(source_directory, destination_directory, dirs_exist_ok=True)
print(f"Directory tree copied to {destination_directory}") directory_to_remove = 'my_project_backup'
if os.path.exists(directory_to_remove):
shutil.rmtree(directory_to_remove)
print(f"Directory {directory_to_remove} removed")
else:
print(f"Directory {directory_to_remove} does not exist") source_item = 'example.txt'
destination_item = 'moved_files/example.txt'
os.makedirs(os.path.dirname(destination_item), exist_ok=True)
shutil.move(source_item, destination_item)
print(f"Item moved to {destination_item}") archive_name = 'my_project_backup'
shutil.make_archive(archive_name, 'zip', 'my_project')
print(f"Archive {archive_name}.zip created") archive_file = 'my_project_backup.zip'
extract_directory = 'extracted_project'
shutil.unpack_archive(archive_file, extract_directory)
print(f"Archive extracted to {extract_directory}") total, used, free = shutil.disk_usage('/')
print(f"Total: {total // (2**30)} GB")
print(f"Used: {used // (2**30)} GB")
print(f"Free: {free // (2**30)} GB")Choose the appropriate library based on your needs: use os.path for simple tasks, pathlib for an object‑oriented approach, glob for pattern‑based file searching, and shutil for advanced file operations such as copying, moving, and archiving.
Test Development Learning Exchange
Test Development Learning Exchange
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.