Creating, renaming and deleting

os · Practical · 9 min

Setup and cleanup code (output folders, temp files, rotations) depends on getting these calls and their errors right.

Directories:

  • os.mkdir(p) creates one directory and fails if the parent is missing or p exists.
  • os.makedirs(p, exist_ok=True) creates all missing parents and does nothing if p already exists. This is the idiom for "ensure the output folder exists".
  • os.rmdir(p) removes an empty directory; os.removedirs also removes empty parents.
  • For a non-empty tree, use shutil.rmtree(p). It deletes without asking, so double-check the path.

Files:

  • os.remove(p) (alias os.unlink) deletes a file. It raises IsADirectoryError or PermissionError for a directory, depending on the platform.
  • os.rename(src, dst) renames or moves within one file system. On Windows it fails if dst exists.
  • os.replace(src, dst) does the same but overwrites dst on every platform, and on POSIX the swap is atomic.
  • To move across file systems or copy, use shutil.move and shutil.copy2.

Errors are specific OSError subclasses: FileExistsError, FileNotFoundError, PermissionError, IsADirectoryError, NotADirectoryError. Catch the one you expect rather than a bare OSError, and prefer "try it and handle the error" over checking exists first, which races with other processes.

Example

import os
import shutil

os.makedirs("out/2024/q1", exist_ok=True)
os.makedirs("out/2024/q1", exist_ok=True)   # no error the second time
with open("out/draft.txt", "w") as f:
    f.write("v1")

os.replace("out/draft.txt", "out/final.txt")  # overwrite-safe rename
print(sorted(os.listdir("out")))  # ['2024', 'final.txt']

try:
    os.rmdir("out")               # not empty
except OSError as e:
    print(type(e).__name__)       # OSError

os.remove("out/final.txt")
shutil.rmtree("out")              # whole tree
print(os.path.exists("out"))      # False

Remember

  • os.makedirs(p, exist_ok=True) is the safe way to ensure a folder
  • os.replace overwrites and is atomic on POSIX; os.rename may fail on Windows
  • Use shutil.rmtree/shutil.move for whole trees and cross-device moves

Watch out for

  • Checking os.path.exists and then creating; another process can win the race, so use exist_ok=True or catch FileExistsError.

Check yourself

  1. You need to save a file to out/reports/2024/ and none of these folders exist yet. Which call prepares them?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/os.html#os.makedirs