Введение: Зачем программисту уметь работать с файлами?
Давайте честно, у кого из нас папка «Загрузки» не превращалась в свалку из документов, архивов и картинок с непонятными именами? Или, может, вы скачали сотню фоток с именами вроде DSC00123.JPG и хотели бы дать им нормальные названия? Делать всё это руками — тоска и пустая трата времени.
И тут на сцену выходит Python со своим встроенным модулем os.
Если коротко, это ваш швейцарский нож для работы с файловой системой прямо из кода. С его помощью можно узнать, где вы находитесь, посмотреть, какие файлы лежат в папке, создать новую директорию, переименовать тысячу файлов одним махом или удалить ненужный хлам. Это уже не просто абстрактные задачки, а реальная автоматизация своей рутины.
Эта статья — для новичков. Для тех, кто уже знает, что такое переменные и циклы, но пока боится подступиться к чему-то прикладному. Мы разберем самые нужные и частые команды модуля os на простых примерах, без воды и заумных терминов.
Теория — это круто, но без практики она быстро выветривается. Поэтому в конце вас ждет не просто перечень команд, а ссылка на мой GitHub с практическими заданиями. Там мы и закрепим всё, о чем здесь поговорим. Поехали!
2. Подготовка к работе: import os
Давайте сразу к делу. Чтобы получить доступ ко всем этим командам, модуль os нужно подключить к нашему скрипту. Это делается одной простой строкой в самом начале вашего .py файла.
import os
И всё. Ничего дополнительно устанавливать через pip не нужно, потому что os — это часть стандартной библиотеки Python, он всегда под рукой.
Небольшой, но важный момент для общего развития:
В современном Python для работы с путями всё чаще используют модуль pathlib. Он предлагает более удобный, объектно-ориентированный подход, и многие считают его более «питоничным».
Так почему мы начинаем с os? Во-первых, это основа основ, и вы будете постоянно встречать его в огромном количестве существующего кода и примеров в интернете. Во-вторых, для простых, прямолинейных задач его синтаксис часто бывает понятнее новичку. Мы изучим базу, а к pathlib вы всегда успеете прийти, когда почувствуете себя увереннее.
3. Где я? Навигация по файловой системе
Окей, модуль мы подключили. Но с чего начать? Прежде чем что-то создавать или удалять, неплохо бы осмотреться. Ваш скрипт, когда запускается, по умолчанию «не видит» ничего, кроме папки, из которой его запустили. Давайте научим его оглядываться по сторонам.
os.getcwd() — узнать текущую рабочую директорию
Первый и самый главный вопрос — где мы вообще находимся? Команда getcwd (get current working directory) — это аналог команды pwd в терминале Linux. Она моментально показывает полный путь к папке, в которой сейчас работает ваш скрипт.
import os
current_directory = os.getcwd()
print(f"Сейчас мой скрипт работает отсюда: {current_directory}")
Если вы запустите этот код, то увидите что-то вроде:
C:\Users\ИмяПользователя\Desktop\my_projectна Windows/home/ИмяПользователя/projects/my_projectна Linux или macOS
Просто и полезно.
os.listdir() — посмотреть, что находится в папке
Хорошо, мы знаем, где мы. А что вокруг нас? Команда listdir покажет всё, что лежит в директории: и файлы, и другие папки. В ответ она возвращает обычный питоновский список со строками.
import os
# Если вызвать без аргументов, покажет содержимое текущей папки
whats_inside = os.listdir()
print("Внутри этой папки лежат:")
print(whats_inside)
# Вывод будет примерно таким:
# Внутри этой папки лежат:
# ['main.py', '.venv', 'data', 'requirements.txt']
Можно заглянуть и в любую другую папку, просто передав ей путь в качестве аргумента: os.listdir('C:/Users/ИмяПользователя/Documents').
os.chdir() — сменить текущую директорию
Это аналог команды cd в терминале. Она позволяет скрипту «перейти» в другую папку и уже оттуда продолжать работу. Это одна из самых часто используемых команд.
Представим, что у нас есть папка data. Давайте зайдем в нее.
import os
print(f"Сначала я здесь: {os.getcwd()}")
# 'Переходим' в папку data (она должна быть внутри текущей директории)
os.chdir('data')
print(f"Теперь я здесь: {os.getcwd()}")
А как вернуться обратно, на уровень выше? Для этого используется стандартное обозначение ...
# Возвращаемся на один уровень вверх
os.chdir('..')
print(f"И снова я здесь: {os.getcwd()}")
Важный момент: если вы попытаетесь перейти в папку, которой не существует, Python выдаст ошибку FileNotFoundError, и скрипт упадет. Всегда будьте уверены, что директория, в которую вы переходите, действительно существует. Позже мы научимся это проверять.
4. Создаем и удаляем: управление папками и файлами
Окей, навигацию освоили. Давайте к самому интересному — будем что-то менять. Создавать папки для будущего порядка, переименовывать файлы и избавляться от мусора.
Работа с папками
os.mkdir() — создать одну папку
Тут всё просто. mkdir (make directory) создает новую папку в текущей директории.
import os
# Создаст папку 'reports' прямо здесь
os.mkdir('reports')
Важный нюанс: если папка reports уже существует, скрипт упадет с ошибкой FileExistsError.
os.makedirs() — создать сразу несколько папок
А что, если нужно создать целую структуру? Например, archive/2025/photos. Если попытаться сделать это через mkdir, он сломается, потому что папки archive еще нет. Вот тут-то и нужен makedirs — он достаточно умен, чтобы создать всё дерево директорий за вас.
import os
# Эта команда создаст и 'archive', и вложенную в нее '2025', и 'photos'
os.makedirs('archive/2025/photos')
Это супер-удобно, и в 90% случаев вы будете использовать именно makedirs.
os.rmdir() — удалить пустую папку
rmdir (remove directory) делает обратное — удаляет папку. Ключевое слово здесь — пустую. Если внутри директории что-то есть, Python откажется ее удалять и выдаст ошибку. Это такая защита от случайного сноса важных данных.
import os
# Сначала создадим, потом удалим
os.mkdir('temp_folder')
os.rmdir('temp_folder')
Работа с файлами
os.rename() — переименовать или переместить файл
А вот тут кроется небольшой трюк. Команда rename делает сразу две вещи.
-
Простое переименование:
import os # Сначала создадим файл, чтобы было с чем работать with open('old_name.txt', 'w') as f: f.write('some text') # А теперь переименуем его os.rename('old_name.txt', 'new_name.txt') -
Перемещение файла: Если вторым аргументом указать путь в другую папку, файл переедет туда.
import os os.makedirs('archive') # Создадим папку для примера # Перемещаем наш файл в папку 'archive' os.rename('new_name.txt', 'archive/new_name.txt')Это очень мощный прием: одной командой и переименовали, и переместили.
os.remove() — удалить файл
Это прямой и беспощадный способ удалить файл. Никаких вопросов, никаких «вы уверены?». Просто берет и удаляет.
import os
# Удаляем файл, который только что переместили
os.remove('archive/new_name.txt')
ВНИМАНИЕ! ОЧЕНЬ ВАЖНЫЙ БЛОК!
Команды os.remove() и os.rmdir() удаляют файлы и папки НАВСЕГДА. Они не перемещают их в Корзину. Отменить это действие нельзя. Один неверный шаг в цикле — и можно случайно снести половину рабочего стола.
Золотое правило: прежде чем запускать скрипт, который что-то удаляет, сначала замените os.remove(path) на print(f"Собираюсь удалить: {path}"). Запустите, посмотрите на список и только потом, будучи на 100% уверенным, возвращайте команду удаления. Не рискуйте.
5. Путь к файлу: магия os.path
Казалось бы, что сложного в путях к файлам? Просто строка, да и всё.
Проблема: разные слэши
На Windows пути к файлам разделяются обратным слэшем: C:\Users\User\Documents.
А на Linux и macOS — прямым: /home/user/documents.
Если вы в своем коде жестко пропишете my_folder + '/' + my_file, ваш скрипт прекрасно сработает на Linux, но сломается на Windows. Это главная головная боль, которую решает подмодуль os.path.
os.path.join() — правильный способ собирать пути
Забудьте про склеивание строк со слэшами. Навсегда. Вместо этого используйте os.path.join(). Эта функция сама понимает, на какой операционной системе она запущена, и подставляет правильный разделитель.
import os
# Просто перечисляем части пути через запятую
folder = 'documents'
filename = 'report.docx'
# os.path.join() сделает всю грязную работу за нас
full_path = os.path.join('C:', 'Users', 'User', folder, filename)
print(full_path)
# На Windows выведет: C:\Users\User\documents\report.docx
# На Linux вывело бы: C:/Users/User/documents/report.docx (с правильными слэшами)
Используйте эту функцию всегда. Это признак хорошего, переносимого кода.
basename и dirname — разбираем пути на запчасти
Часто нужно сделать обратное: из полного пути получить только имя файла или только путь к папке, в которой он лежит.
os.path.basename(path)— возвращает имя файла.os.path.dirname(path)— возвращает путь к директории.
import os
full_path = '/home/user/documents/report.docx'
filename = os.path.basename(full_path)
print(f"Имя файла: {filename}") # Выведет: Имя файла: report.docx
directory = os.path.dirname(full_path)
print(f"Путь к папке: {directory}") # Выведет: Путь к папке: /home/user/documents
Невероятно полезно, когда нужно работать с файлами, не зная их точных имен заранее.
Проверки — работаем безопасно
Это, возможно, самый важный блок в этой главе. Помните, мы говорили, что скрипт упадет, если попытаться перейти в несуществующую папку? Или создать папку, которая уже есть? Чтобы этого избежать, нужно проверять, существует ли путь, прежде чем что-то с ним делать.
os.path.exists(path)— самая частая проверка. ВозвращаетTrue, если путь (файл или папка) существует, иFalse, если нет.os.path.isfile(path)— возвращаетTrue, только если это существующий файл.os.path.isdir(path)— возвращаетTrue, только если это существующая папка.
Вот как это выглядит на практике:
import os
path_to_check = 'archive'
if os.path.exists(path_to_check):
print(f"Путь '{path_to_check}' существует.")
if os.path.isdir(path_to_check):
print("И это папка!")
elif os.path.isfile(path_to_check):
print("И это файл!")
else:
print(f"Пути '{path_to_check}' не существует. Давайте создадим папку.")
os.makedirs(path_to_check)
Этот простой шаблон с if делает ваш код в сто раз надежнее. Сначала проверяем, потом делаем. Всегда.
6. Собираем все вместе: пишем скрипт для сортировки файлов
Хватит теории. Давайте напишем что-то, что можно запустить и сразу увидеть результат. Помните проблему с папкой «Загрузки», которую мы обсуждали в самом начале? Вот ее мы и решим.
Постановка задачи:
У нас есть папка, заваленная разными файлами: картинками (.jpg, .png), документами (.pdf, .docx) и архивами (.zip). Наша цель — написать скрипт, который:
Сам создаст внутри этой папки директории:
Images,Documents,ArchivesиOther.Пройдется по всем файлам.
Рассортирует каждый файл в соответствующую папку в зависимости от его расширения.
План-алгоритм скрипта (наша логика):
Прежде чем писать код, давайте проговорим шаги. Наш скрипт должен:
Определить путь к папке, где будем наводить порядок.
Получить список всего, что в ней лежит.
Запустить цикл и по очереди рассматривать каждый элемент из этого списка.
Внутри цикла первым делом проверить: это файл или папка? Сортируем мы только файлы.
Если это файл, смотрим на его расширение (то, что после последней точки в имени).
В зависимости от расширения, решаем, в какую целевую папку (
Images,Documentsи т.д.) его нужно положить.Перед перемещением проверяем, а существует ли вообще эта целевая папка? Если нет — создаем ее.
Перемещаем файл в нужную папку.
Звучит логично. Теперь переведем это на язык Python.
Код:
import os
import shutil # Этот модуль мы не проходили, но его метод move надежнее для перемещения
# 1. УКАЖИТЕ ПУТЬ К ВАШЕЙ ПАПКЕ ДЛЯ СОРТИРОВКИ!
# ВАЖНО: Используйте двойные слэши \\ для Windows или одинарные / для Linux и macOS
PATH_TO_SORT = "C:\\Users\\YourUser\\Downloads\\TestFolder" # <-- ИЗМЕНИТЕ ЭТОТ ПУТЬ
# 2. Получаем список всех файлов и папок в директории
all_items = os.listdir(PATH_TO_SORT)
# 3. Проходимся по каждому элементу
for item in all_items:
# Собираем полный путь к файлу, чтобы с ним можно было работать
item_full_path = os.path.join(PATH_TO_SORT, item)
# 4. Проверяем, что это файл, а не папка
if os.path.isfile(item_full_path):
try:
# 5. Получаем расширение файла в нижнем регистре
extension = item.split('.')[-1].lower()
# 6. Определяем, в какую папку положить файл
target_folder = ''
if extension in ['jpg', 'jpeg', 'png', 'gif', 'bmp']:
target_folder = 'Images'
elif extension in ['pdf', 'docx', 'doc', 'txt', 'xlsx']:
target_folder = 'Documents'
elif extension in ['zip', 'rar', '7z']:
target_folder = 'Archives'
else:
target_folder = 'Other'
# Собираем путь к целевой папке
target_folder_path = os.path.join(PATH_TO_SORT, target_folder)
# 7. Проверяем, существует ли папка. Если нет - создаем.
if not os.path.exists(target_folder_path):
os.makedirs(target_folder_path)
print(f"Создана папка: {target_folder}")
# 8. Перемещаем файл
# Используем shutil.move, он корректно работает между разными дисками
# и в целом более предсказуем, чем os.rename для перемещения
shutil.move(item_full_path, target_folder_path)
print(f"Файл '{item}' перемещен в папку '{target_folder}'")
except Exception as e:
# На случай, если у файла нет расширения или возникла другая ошибка
print(f"Не удалось обработать файл '{item}'. Ошибка: {e}")
print("\nСортировка завершена!")
Вот и всё! Этот скрипт — отличный пример того, как несколько простых команд модуля os (и одна из shutil для надежности) могут превратиться в полезную программу-автоматизатор. Можете скопировать его, изменить путь и попробовать на тестовой папке.
7. Заключение и что дальше?
Ну вот и всё! Если вы дочитали до этого момента и попробовали запустить код, то поздравляю: вы сделали огромный шаг от написания абстрактных «hello, world» к созданию реально полезных скриптов.
Давайте быстро пробежимся по тому, что мы теперь умеем:
Осматриваться в файловой системе с помощью
getcwdиlistdir.Перемещаться между папками через
chdir.Создавать и удалять папки (
mkdir,makedirs,rmdir).Переименовывать, перемещать и удалять файлы (
rename,remove).И, что самое главное, — писать кросс-платформенный и безопасный код, используя проверки из
os.path.
Мы собрали все эти знания в одном скрипте, который наводит порядок в папках. Это и есть настоящая автоматизация: скучную ручную работу мы переложили на плечи Python.
Куда двигаться дальше?
Мир работы с файлами не ограничивается одним модулем os. Если эта тема вас зацепила, вот пара советов для дальнейшего изучения:
Посмотрите в сторону
pathlib. Как я уже упоминал, это более современная и объектно-ориентированная библиотека для работы с путями. Код с ней часто выглядит чище и интуитивнее. Считать, чтоosустарел — неправильно, но знать проpathlibи уметь им пользоваться — это признак хорошего тона в современном Python.Попробуйте автоматизировать что-то свое. Подумайте, какие рутинные задачи с файлами вы выполняете на своем компьютере? Может, нужно бэкапить какие-то документы по расписанию? Или искать файлы-дубликаты? Попробуйте набросать для этого свой собственный скрипт.
Спасибо, что уделили время этой статье. Надеюсь, она была для вас полезной. А теперь — к самому главному.
8. Домашнее задание на GitHub
Как и обещал в самом начале, просто прочитать статью — недостаточно. Настоящие нейронные связи в мозгу формируются только тогда, когда вы сами пишете код, сталкиваетесь с ошибками и исправляете их.
Поэтому я подготовил для вас репозиторий, где вы сможете отточить все, о чем мы сегодня говорили.
>> Ссылка на репозиторий с заданиями на GitHub <<
Что вас ждет внутри? Не просто список задач, а нечто лучшее. Рядом с каждым заданием лежат готовые тесты, которые автоматически проверят ваш код. Вам не придется гадать, «а правильно ли я всё сделал?». Просто пишете решение, запускаете проверку, и она вам тут же скажет, всё ли работает как надо.
Вся подробная инструкция — как скачать репозиторий, как запустить тесты и что именно от вас требуется в каждом задании — находится в файле README.md в корне репозитория.
Если что-то будет непонятно или заметите ошибку, не стесняйтесь создавать 'Issue' на GitHub. А пообщаться, задать вопросы и обсудить решения можно в моем телеграм-блоге — заходите, буду рад помочь: Cсылка.
Уверен, у вас все получится. Вперед, к практике
Markscheider
А зачем это делать в каждой итерации цикла? Не бог весть какая нагрузка на процессор, конечно, но все же...
Я бы перед циклом один раз создал структуру папок. Тем более она все равно захардкожена (Картинки Документы Архивы Прочее).
А если раздражают пустые папки - в конце программы проверил бы их и удалил те, в которых ничего не нападало...
crushilov
Тем более, когда у метода есть для этого готовый аттрибут exist_ok . https://docs.python.org/3/library/os.html#os.makedirs
А также есть еще метод https://docs.python.org/3/library/os.html#os.walk который кажется упростил бы вам алгоритм, чтобы не проверять что есть файл, а что есть директория.
И вообще, после прочтения статьи складывается ощущение, что библиотека
osимеет какой-то сильно ограниченный функционал.А если основной задачей является показать как работать с директориями, файлами и путями, то возможно стоило рассмотреть или сравнить с
pathlib?