Python OS Module
The os module lets your program work with the operating system: create and list folders, build file paths that work on every OS, rename and delete files, and read environment variables. Its modern partner, pathlib, does the same jobs with path objects.
- Create, list and remove folders
- Build portable paths with os.path and pathlib
- Walk a whole folder tree
- Read environment variables
The current folder
Relative paths are resolved against the current working directory, the folder the program was started from.
import os print(os.path.basename(os.getcwd()))print(os.name) # 'nt' on Windows, 'posix' on macOS and Linuxos nt
The examples on this page were run on Windows, so paths print with \. On macOS and Linux you will see / instead. The code is the same.
Create folders and files
import os os.makedirs("reports/2026/nov", exist_ok=True) # creates every missing levelwith open("reports/2026/nov/summary.txt", "w") as f: f.write("all tests passed")with open("reports/readme.md", "w") as f: f.write("# Reports") print(os.listdir("reports"))print(os.path.exists("reports/2026/nov/summary.txt"))['2026', 'readme.md'] True
exist_ok=True stops makedirs from raising an error when the folder already exists.
Check what a path is
import os for p in ["reports", "reports/readme.md", "missing.txt"]: print(p, os.path.exists(p), os.path.isdir(p), os.path.isfile(p)) print(os.path.getsize("reports/readme.md"), "bytes")reports True True False reports/readme.md True False True missing.txt False False False 9 bytes
Build and split paths
Never glue paths together with + "/". os.path.join uses the right separator for the OS:
import os path = os.path.join("reports", "2026", "nov", "summary.txt")print(path)print(os.path.dirname(path))print(os.path.basename(path))print(os.path.splitext(path))reports\2026\nov\summary.txt
reports\2026\nov
summary.txt
('reports\\2026\\nov\\summary', '.txt')Walk a folder tree
os.walk() visits every folder under a starting point and gives you its files:
import os for folder, subfolders, files in os.walk("reports"): level = folder.count(os.sep) print(" " * level + os.path.basename(folder) + "/") for name in files: print(" " * (level + 1) + name)reports/
readme.md
2026/
nov/
summary.txtRename, move and delete
import os, shutil os.rename("reports/readme.md", "reports/README.md")print(sorted(os.listdir("reports"))) os.remove("reports/README.md") # delete a fileshutil.rmtree("reports/2026") # delete a folder and everything in itprint(os.listdir("reports"))os.rmdir("reports") # delete an empty folderprint(os.path.exists("reports"))['2026', 'README.md'] [] False
os.remove and shutil.rmtree delete permanently; there is no recycle bin. Print the path first when you build it from variables.
Environment variables
Environment variables pass settings such as API keys and base URLs to a program without hard-coding them.
import os os.environ["APP_ENV"] = "staging" # set for this processprint(os.environ["APP_ENV"])print(os.environ.get("BASE_URL", "https://sqatools.in")) # with a defaultprint("PATH" in os.environ)stagingHomeTrue
Read secrets with os.environ.get("API_TOKEN") instead of writing them in your code, so they never end up in Git.
pathlib: the modern way
pathlib.Path objects join with / and have methods for most file jobs:
from pathlib import Path base = Path("data")(base / "logs").mkdir(parents=True, exist_ok=True)log = base / "logs" / "run.log"log.write_text("start\nend\n") print(log.name, log.suffix, log.stem)print(log.parent.name)print(log.read_text().splitlines())print([p.name for p in base.rglob("*.log")])run.log .log run logs ['start', 'end'] ['run.log']
| Task | os / os.path | pathlib |
|---|---|---|
| Join paths | os.path.join(a, b) | Path(a) / b |
| Exists | os.path.exists(p) | p.exists() |
| Make folders | os.makedirs(p, exist_ok=True) | p.mkdir(parents=True, exist_ok=True) |
| List | os.listdir(p) | p.iterdir() |
| Read text | open(p).read() | p.read_text() |
| Extension | os.path.splitext(p)[1] | p.suffix |
Check your understanding
Quick quiz
1. Which function creates nested folders in one call?
makedirs creates every missing level; mkdir creates only one.
2. Why use os.path.join instead of string concatenation?
Windows uses \ and Linux uses /; join handles both.
3. How do you read an environment variable safely with a default?
get() returns the default instead of raising KeyError. os.getenv("X", "default") also works.
Exercise: group files by extension
Create a few files in a folder, then count how many files there are of each extension.
a.py, b.py, notes.txt, data.csv, c.py
.py 3 .csv 1 .txt 1
Hint 1
os.path.splitext(name)[1] gives the extension; a Counter counts them.
import osfrom collections import Counter os.makedirs("project", exist_ok=True)for name in ["a.py", "b.py", "notes.txt", "data.csv", "c.py"]: open(os.path.join("project", name), "w").close() extensions = Counter(os.path.splitext(n)[1] for n in os.listdir("project"))for ext, count in extensions.most_common(): print(ext, count).py 3 .csv 1 .txt 1
open(...).close() creates an empty file. The generator expression pulls the extension from every file name, and Counter tallies them.
Program Practice
49 Python OS Module Programs
Every program has a step-by-step explanation, colour-coded code and its real output.
Python os module FAQ
How do I get the current directory in Python?
os.getcwd() returns it as a string; Path.cwd() returns it as a Path object.
How do I check if a file exists in Python?
os.path.exists(path) or Path(path).exists(). Use isfile() / isdir() to check the type too.
What is the difference between os and pathlib?
os and os.path work with paths as strings. pathlib (Python 3.4+) wraps paths in objects with methods and the / operator. pathlib is usually more readable for new code.
How do I delete a folder that is not empty?
Use shutil.rmtree(path). os.rmdir only removes empty folders.
2 thoughts on “Python OS Module”