Python os Module: Manage Files and Folders

Published on: July 10, 2026
Reading time: 5 minutes
Manipulação de arquivos e pastas usando módulo os em Python

Python programs often need to interact with the operating system. A script may create folders, list files, rename reports, read environment variables, or organize downloads. The Python os module provides standard tools for these tasks without requiring an external package.

This guide explains the most useful parts of os and os.path for beginners. You will learn how to inspect the current directory, create nested folders, join paths safely, rename and delete files, walk through directory trees, read environment variables, and build a practical file organizer.

For newer object-oriented path handling, also read the companion guide to Python pathlib. The two modules can work together: os remains important for environment variables, process information, permissions, and many operating-system operations, while pathlib often produces clearer path code.

What Is the Python os Module?

os is part of Python’s standard library. It exposes portable operating-system interfaces so the same program can perform many file and directory tasks on Windows, macOS, and Linux.

import os

print(os.name)
print(os.getcwd())

os.name gives a broad platform identifier such as "nt" on Windows or "posix" on Unix-like systems. For detailed platform information, use the separate platform module.

The official Python os documentation lists the full API. The related os.path reference covers pathname operations.

Find and Change the Current Working Directory

The current working directory is the folder Python uses to resolve relative paths.

import os

current_directory = os.getcwd()
print(current_directory)

os.chdir("data")
print(os.getcwd())

os.chdir() changes the process’s working directory. Use it carefully because every later relative path will be interpreted from the new location. In many scripts, keeping the working directory unchanged and building explicit paths is easier to reason about.

Path confusion is a common cause of missing-file errors. The guide to fixing Python FileNotFoundError explains how to diagnose those cases.

List Files and Folders

os.listdir() returns the names inside a directory:

import os

for name in os.listdir("."):
    print(name)

The result includes files and subdirectories but not their full paths. Join each name to the parent directory before inspecting it.

base_directory = "reports"

for name in os.listdir(base_directory):
    full_path = os.path.join(base_directory, name)

    if os.path.isfile(full_path):
        print("File:", full_path)
    elif os.path.isdir(full_path):
        print("Folder:", full_path)

Join Paths Safely with os.path.join()

Do not build filesystem paths by manually adding slashes. Different operating systems use different separators, and duplicate separators are easy to introduce.

folder = "exports"
filename = "sales.csv"

path = os.path.join(folder, filename)
print(path)

os.path.join() uses the correct separator for the current platform. The companion guide on pathlib paths shows the modern alternative: Path("exports") / "sales.csv".

Create Directories

os.mkdir() creates one folder. Its parent must already exist.

os.mkdir("output")

os.makedirs() can create an entire nested structure:

os.makedirs(
    os.path.join("project", "logs", "archive"),
    exist_ok=True,
)

exist_ok=True prevents an error when the final directory already exists. It does not hide every possible failure: permissions and invalid paths can still raise exceptions.

Rename and Move Files

os.rename() can rename an item or move it to another location on the same filesystem.

old_path = os.path.join("reports", "draft.csv")
new_path = os.path.join("reports", "sales-2026.csv")

os.rename(old_path, new_path)

When moving files between different disks or filesystems, shutil.move() is usually more flexible. See the guide to copying and moving files with shutil for complete examples.

Delete Files and Empty Folders

file_path = os.path.join("temp", "old-report.txt")

if os.path.isfile(file_path):
    os.remove(file_path)

Use os.rmdir() to remove an empty directory:

empty_folder = os.path.join("temp", "empty")

if os.path.isdir(empty_folder):
    os.rmdir(empty_folder)

These operations normally bypass the desktop recycle bin. Confirm the path before deleting anything, especially when the value comes from user input or configuration. To remove a directory tree, use shutil.rmtree() only after adding strong safeguards.

Inspect Path Components

path = os.path.join("data", "archive", "customers.csv")

print(os.path.basename(path))   # customers.csv
print(os.path.dirname(path))    # data/archive
print(os.path.splitext(path))   # (.../customers, .csv)
print(os.path.abspath(path))

splitext() separates the final extension from the rest of the path. It is useful for classifying files by type, but remember that a suffix is only a naming convention; it does not prove the actual file format.

Check Whether a Path Exists

path = os.path.join("config", "settings.json")

if os.path.exists(path):
    print("The path exists")

if os.path.isfile(path):
    print("It is a file")

if os.path.isdir(path):
    print("It is a directory")

Existence checks can help produce friendly messages, but they do not replace exception handling. Another process may change the file after your check. Open or modify the resource inside an appropriate try/except block when reliability matters.

Walk Through a Directory Tree

os.walk() recursively visits a directory and yields the current folder, its subfolder names, and its filenames.

for current_folder, subfolders, filenames in os.walk("project"):
    print("Folder:", current_folder)

    for filename in filenames:
        file_path = os.path.join(current_folder, filename)
        print("  ", file_path)

This is useful for backups, storage reports, code searches, and bulk conversion. For recurring backup work, the automatic Python backup guide provides a larger workflow.

Read and Set Environment Variables

Environment variables store configuration outside source code. They are commonly used for modes, service addresses, and secret identifiers.

import os

environment = os.getenv("APP_ENV", "development")
api_url = os.getenv("API_URL")

print(environment)
print(api_url)

os.getenv() returns None or a supplied default when the variable is missing. You can also access os.environ like a mapping:

os.environ["APP_MODE"] = "test"
print(os.environ["APP_MODE"])

A value assigned this way affects the current process and child processes, not the user’s permanent system configuration. Never print secrets or commit them to source control. The guide to reading environment variables safely covers validation and .env files.

Get File Metadata

path = os.path.join("reports", "sales.csv")
metadata = os.stat(path)

print("Size:", metadata.st_size)
print("Modified timestamp:", metadata.st_mtime)

os.stat() returns metadata such as size, timestamps, and permission information. Timestamp values are seconds since the platform epoch; use datetime to convert them into readable dates.

Practical Project: Organize Files by Extension

The following script scans one directory and moves files into category folders. It uses os for inspection and directory creation, and shutil.move() for robust moves.

import os
import shutil


CATEGORIES = {
    "images": {".jpg", ".jpeg", ".png", ".gif", ".webp"},
    "documents": {".pdf", ".docx", ".txt", ".xlsx", ".csv"},
    "archives": {".zip", ".rar", ".7z", ".tar", ".gz"},
    "code": {".py", ".js", ".html", ".css", ".json"},
}


def category_for(filename):
    extension = os.path.splitext(filename)[1].lower()

    for category, extensions in CATEGORIES.items():
        if extension in extensions:
            return category

    return "other"


def unique_destination(folder, filename):
    stem, extension = os.path.splitext(filename)
    candidate = os.path.join(folder, filename)
    number = 1

    while os.path.exists(candidate):
        candidate = os.path.join(
            folder,
            f"{stem}-{number}{extension}",
        )
        number += 1

    return candidate


def organize_files(directory):
    directory = os.path.abspath(directory)

    if not os.path.isdir(directory):
        raise NotADirectoryError(directory)

    moved = 0

    for filename in os.listdir(directory):
        source = os.path.join(directory, filename)

        if not os.path.isfile(source):
            continue

        category = category_for(filename)
        destination_folder = os.path.join(directory, category)
        os.makedirs(destination_folder, exist_ok=True)

        destination = unique_destination(
            destination_folder,
            filename,
        )

        shutil.move(source, destination)
        moved += 1
        print(f"Moved {filename} to {category}/")

    return moved


if __name__ == "__main__":
    total = organize_files("downloads-test")
    print(f"Finished: {total} files moved")

The function avoids overwriting an existing file by adding a number to the destination name. For unattended use, replace or supplement print() with Python logging.

os vs. pathlib vs. shutil

ModuleBest suited for
osEnvironment variables, process and platform operations, directory functions, low-level OS interfaces.
os.pathString-based path inspection and manipulation.
pathlibReadable, object-oriented path and file operations.
shutilHigh-level copying, moving, archiving, and directory-tree operations.

You do not have to choose only one. Real applications often use all three where each is clearest.

Common Mistakes

  • Concatenating paths with hard-coded slashes.
  • Assuming the working directory is the script directory.
  • Deleting a path without confirming what it points to.
  • Ignoring permissions and file-lock errors.
  • Using os.rename() for cross-filesystem moves without a fallback.
  • Logging environment-variable secrets.
  • Checking existence but not handling a later operation failure.

Frequently Asked Questions

Do I need to install os?

No. It is included in Python’s standard library.

How do I get the script’s directory?

Use os.path.dirname(os.path.abspath(__file__)). In interactive environments, __file__ may not exist.

How do I create nested folders?

Use os.makedirs(path, exist_ok=True).

Can os move a file?

os.rename() can move or rename files in supported situations. Use shutil.move() for a higher-level solution, especially across filesystems.

Is pathlib replacing os?

No. Pathlib replaces many string-based path tasks, but os still exposes operating-system features that pathlib does not.

Conclusion

The Python os module is a foundational tool for automation and system interaction. Learn getcwd(), listdir(), makedirs(), os.path.join(), environment variables, and safe deletion first. Then add os.walk(), metadata, permissions, and process features as your projects require them.

Use explicit paths, validate destructive operations, and handle exceptions around real filesystem work. Those habits make scripts safer and easier to run on different computers.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Barra de progresso com tqdm para scripts Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python tqdm: Add Progress Bars to Scripts

    Add progress bars to Python scripts with tqdm. Learn installation, loops, manual updates, files, pandas, nested bars, and practical options.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026
    Uso do módulo random para gerar valores aleatórios em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python random Module: Complete Beginner Guide

    Learn Python's random module: generate numbers, choose items, shuffle lists, sample data, use seeds, and know when to use secrets.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Manipulação moderna de arquivos usando pathlib em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python pathlib: Manage Files and Paths Easily

    Learn Python pathlib to create, inspect, read, write, rename, move, and delete files and folders with clean cross-platform code.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Uso do Counter do collections para contar elementos em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python Counter: Count Items with collections

    Learn Python Counter to count items, find common values, update totals, compare counts, and solve practical frequency problems.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026
    Como evitar KeyError usando defaultdict em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Avoid Python KeyError with defaultdict

    Learn how defaultdict prevents Python KeyError, when to use default_factory, how it compares with dict.get, setdefault, Counter, and common mistakes.

    Ler mais

    Tempo de leitura: 7 minutos
    28/05/2026
    Introdução ao módulo itertools para iniciantes em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python itertools: Practical Beginner Guide

    Learn Python itertools with practical examples of count, cycle, repeat, chain, combinations, permutations, groupby, tee, and memory-efficient iteration.

    Ler mais

    Tempo de leitura: 8 minutos
    28/05/2026