Python: уроки, справочник и задачи

Модуль os: работа с файловой системой из Python

Раздел: Работа с файлами в Python · Обновлено 31.10.2026

Модуль os в Python дает доступ к функциям операционной системы: текущему каталогу, списку файлов, созданию и удалению папок, путям и переменным окружения. Он входит в стандартную библиотеку, поэтому устанавливать ничего не нужно, достаточно написать import os. Ниже разобраны функции, которые чаще всего встречаются в реальных скриптах, с рабочими примерами и разбором ошибок.

Модуль os
Фото: Ian Dexter Marquez from Pasig City, Philippines / CC BY-SA 2.0, Wikimedia Commons
Содержание статьи
  1. Что входит в модуль os
  2. Текущий каталог и переход между папками
  3. Список файлов в каталоге
    1. os.scandir для больших папок
    2. Обход дерева каталогов через os.walk
  4. Создание, переименование и удаление
    1. Папки: mkdir и makedirs
    2. Файлы: remove, rename и replace
  5. Подмодуль os.path для работы с путями
  6. Переменные окружения и сведения о системе
  7. Запуск системных команд
  8. Частые вопросы
    1. Нужно ли устанавливать модуль os через pip?
    2. Как проверить, существует ли файл?
    3. Почему os.remove не удаляет папку?
    4. Как получить путь к папке, где лежит скрипт?
    5. Что выбрать: os.path или pathlib?

Что входит в модуль os

Модуль собирает в одном месте вызовы, которые в разных системах устроены по-разному. Один и тот же код с os.listdir() или os.path.join() работает в Windows, Linux и macOS. Часть функций доступна только в Unix, например os.fork() и os.getuid(), и в Windows их вызов закончится AttributeError.

Функции модуля удобно разделить на группы:

Полный перечень функций с пометками о поддерживаемых платформах есть в официальной документации os.

Текущий каталог и переход между папками

Относительные пути вроде "data.txt" Python ищет от текущего рабочего каталога. Это не обязательно папка, где лежит скрипт: если запустить программу из другой директории, файл не найдется. Узнать текущий каталог помогает os.getcwd(), сменить его можно через os.chdir().

import os

print(os.getcwd())          # C:\Users\user\project

script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)        # теперь пути считаются от папки скрипта
print(os.getcwd())

Менять рабочий каталог в больших программах лучше осторожно: это глобальная настройка процесса, и она влияет на все модули. Надежнее строить полные пути от script_dir и передавать их в функции.

Список файлов в каталоге

Функция os.listdir(path) возвращает список имен файлов и папок без полного пути и в произвольном порядке. Если аргумент не передан, берется текущий каталог. Для сортировки результат оборачивают в sorted().

import os

for name in sorted(os.listdir(".")):
    full = os.path.join(".", name)
    kind = "папка" if os.path.isdir(full) else "файл"
    print(f"{kind}: {name}")

os.scandir для больших папок

os.scandir() возвращает итератор объектов DirEntry. У каждого есть name, path, методы is_file(), is_dir() и stat(). Тип файла часто известен системе сразу, поэтому лишних обращений к диску меньше, и на тысячах файлов scandir() работает заметно быстрее связки listdir() и os.path.isfile().

import os

with os.scandir(".") as entries:
    for entry in entries:
        if entry.is_file() and entry.name.endswith(".py"):
            print(entry.name, entry.stat().st_size, "байт")

Обход дерева каталогов через os.walk

os.walk(top) рекурсивно проходит все вложенные папки и на каждом шаге отдает кортеж из трех значений: путь к текущей папке, список подпапок и список файлов. Список подпапок можно менять на ходу, чтобы пропустить ненужные каталоги.

import os

total = 0
for root, dirs, files in os.walk("project"):
    dirs[:] = [d for d in dirs if d not in (".git", "__pycache__")]
    for name in files:
        total += os.path.getsize(os.path.join(root, name))
print(f"Размер: {total / 1024:.1f} КБ")

Если нужен поиск по шаблону вроде *.csv, короче получится с модулем glob.

Создание, переименование и удаление

Функции этой группы меняют файловую систему, поэтому чаще других вызывают исключения: FileExistsError, FileNotFoundError, PermissionError. В рабочем коде их стоит перехватывать или заранее проверять условия.

Папки: mkdir и makedirs

os.mkdir() создает одну папку и падает, если родительского каталога нет. os.makedirs() создает всю цепочку, а с параметром exist_ok=True не выдает ошибку, когда папка уже существует.

import os

os.makedirs("reports/2026/october", exist_ok=True)

try:
    os.mkdir("reports")
except FileExistsError:
    print("Папка reports уже есть")

Файлы: remove, rename и replace

os.remove() удаляет файл, а для пустой папки нужен os.rmdir(). Переименование и перемещение в пределах одного диска выполняет os.rename(src, dst). В Windows он выдает ошибку, если dst уже существует, а os.replace() в этом случае молча перезапишет файл на любой системе.

import os

with open("draft.txt", "w", encoding="utf-8") as f:
    f.write("черновик")

os.replace("draft.txt", "final.txt")
if os.path.exists("final.txt"):
    os.remove("final.txt")

Удалить непустую папку целиком или скопировать дерево каталогов модуль os не умеет. Для этого есть модуль shutil с функциями rmtree() и copytree().

Подмодуль os.path для работы с путями

Склеивать пути через + и слеш опасно: в Windows разделитель обратный, и легко получить двойной или пропущенный слеш. os.path берет это на себя и подставляет разделитель текущей системы.

ФункцияЧто делаетПример результата
join(a, b)соединяет части путиdata/2026/log.txt
exists(p)есть ли файл или папкаTrue
isfile(p), isdir(p)проверяет тип объектаTrue / False
basename(p)имя файла из путиlog.txt
dirname(p)путь к папкеdata/2026
splitext(p)отделяет расширение('data/2026/log', '.txt')
abspath(p)полный путь от корня/home/user/data/2026/log.txt
getsize(p)размер файла в байтах2048
import os

path = os.path.join("data", "2026", "log.txt")
name, ext = os.path.splitext(os.path.basename(path))
print(name, ext)  # log .txt

В новом коде вместо os.path часто используют объектный подход модуля pathlib, его сравнение со старыми функциями есть в статье pathlib вместо os.path.

Переменные окружения и сведения о системе

os.environ ведет себя как словарь со всеми переменными окружения процесса. Для чтения безопаснее os.getenv("NAME", default): при отсутствии переменной он вернет значение по умолчанию вместо KeyError. Так обычно передают в программу токены, пароли к базе и режим отладки, чтобы не хранить их в коде.

import os

debug = os.getenv("APP_DEBUG", "0") == "1"
os.environ["APP_MODE"] = "test"   # видно только этому процессу и его потомкам

print(os.name)        # 'nt' в Windows, 'posix' в Linux и macOS
print(os.sep)         # разделитель пути: '\\' или '/'
print(os.cpu_count()) # число логических ядер
print(os.getpid())    # номер текущего процесса

Изменения в os.environ не сохраняются в системе после завершения скрипта: они действуют только внутри процесса и передаются запущенным из него программам.

Запуск системных команд

os.system("команда") выполняет строку в командной оболочке и возвращает код завершения, но вывод команды получить нельзя, он сразу идет в консоль. os.popen() позволяет прочитать вывод, однако оба способа передают строку в оболочку целиком, и подстановка пользовательского ввода в такую строку открывает дорогу для инъекций.

Для новых программ документация советует модуль subprocess. Аргументы передаются списком, без оболочки, а результат содержит код возврата и вывод.

import subprocess

result = subprocess.run(["python", "--version"], capture_output=True, text=True)
print(result.returncode)      # 0
print(result.stdout.strip())  # Python 3.12.4

Частые вопросы

Ниже ответы на вопросы, с которыми чаще всего сталкиваются при работе с модулем os.

Нужно ли устанавливать модуль os через pip?

Нет. Модуль входит в стандартную библиотеку и доступен в любой установке Python, достаточно импортировать его командой import os.

Как проверить, существует ли файл?

Используйте os.path.exists(path) для любого объекта или os.path.isfile(path), если нужно убедиться, что это именно файл, а не папка с таким же именем.

Почему os.remove не удаляет папку?

os.remove() работает только с файлами. Пустую папку удаляет os.rmdir(), а папку с содержимым shutil.rmtree().

Как получить путь к папке, где лежит скрипт?

Выражение os.path.dirname(os.path.abspath(__file__)) возвращает каталог текущего файла независимо от того, откуда запущена программа.

Что выбрать: os.path или pathlib?

Оба варианта рабочие. pathlib удобнее читается и объединяет пути оператором /, а os.path встречается в старом коде и в библиотеках, поэтому знать стоит оба.