В этой статье пойдет речь о работе с файлами, папками, командной строкой и другими сущностями операционных систем. Взаимодействие с операционной системой будет осуществляться через встроенную библиотеку os.
Придумываем задачу
Нам нужно изучить работу с файлами, директориями (папками) и командной строкой. Как по мне, так для изучения этих аспектов нет ничего лучше, чем написать скрипт, который бы перемещал определённые файлы из одной папки в другую и архивировал их. Простейший бэкап-скрипт. Поэтому в процессе добавим к изучению еще и библиотеку zipfile.
Декомпозируем задачу:
- Получаем список файлов для обработки
- Осуществляем перемещение файлов в заданную директорию
- Архивируем
Переходим к решению.
Основы основ
Итак, начнем. И как всегда с импорта нужной библиотеки, в нашем случае это OS и стандартной "обёртки" скрипта. Кстати, я вроде бы не говорил зачем нужно это странное условие:
if __name__ == "__main__":
Оно разделяет все переменные и функции скрипта от его исполняемой части. В Python часть можно встретить импорт одних скриптов другими, чтобы воспользоваться их переменными и функциями, так вот, чтобы при таком импорте не запустился основной сценарий, его и отделяют такой фразой.
Выведем на экран фразу "Start", чтобы всем было понятно, что мы начинаем работать и выровняем ее по центру (с помощью метода center), дополнив справа и слева минусами до общей длины в 80 символов - только лишь для красоты.
Получаем список файлов для обработки
Решаем первую задачу. Определимся с директорией, пусть эта директория будет рядом с нашим скриптом, для удобства, и имя у нее будет - files (можете указать любой путь). Для начала, нам нужно посмотреть в эту директорию и узнать, что в ней есть, но смотреть будем не проводником, а скриптом, пишем функцию, которая умеет это делать:
В ответ на применение функции os.listdir мы получили список файлов в интересующей нас директории. Но функция get_files_list выглядит слишком простой, давайте немного ее усложним - заставим не возвращать файлы изображений с расширением jpg - они все равно плохо сжимаются архиватором:
Снова лямбда функция почти как в предыдущей статье. Вкратце:
- Описываем лямбда-функцию, которая будет возвращать True, если преданная ей строка (в нашем случае - имя файла) в нижнем регистре (метод lower) не будет оканчиваться на .jpg (функция endswith).
- Передаем функции filter в качестве первого аргумента эту лямбда-функцию, в качестве второго наш список имен файлов, который она должна профильтровать.
- Преобразуем полученный результат в список, так как функция filter возвращает данные другого типа и возвращаем его как результат работы функции get_files_list.
Вот и всё, список файлов для перемещения получен.
Отмечу, что вместо функции os.listdir можно использовать функцию os.walk - она более универсальная, но громоздкая. С ней лучше работать, когда необходимо буквально "бегать" по дереву каталогов и находить необходимые файлы.
Перемещаем файлы
Вот и вторая задача. Определимся с директорией, куда мы хотим переместить файлы, пусть это будет директория archive. Напишем функцию, которая будет перемещать файлы в целевую директорию. Перемещение осуществляется с помощью одноимённой функцией os.replace, которая принимает на вход путь к файлу-источнику и путь в файлу-назначению:
Много непонятного? Объясняю. На вход функция получает два аргумента - путь к исходному файлу - source_file и директорию, в которой он должен быть расположен после перемещения - destination_dir. Так как файл мы переименовывать не будем, то в первой строке функции при помощи функции os.basename мы получаем его имя из пути к нему. Во второй строке, при помощи функции os.path.join мы "склеиваем" имя файла и целевую директорию в путь к файлу. Затем, с помощью функции перемещения перекладываем файл и возвращаем путь к нему.
Напишем "обвязку" к нашей функции, которая будет передавать ей пути к файлам, которые нужно переместить. Проходим по списку файлов, "склеиваем" их с именем папки при помощи функции os.path.join и вызываем новую функцию move_to_archive, сохраняя ее результат в переменную. Сразу выведем на экран результат работы:
Вуаля, файлы перемещены. Переходим к следующей задаче.
Архивация
Дабы перемещённые файлы не занимали много места - заархивириуем их. На помощь нам придет стандартная библиотека zipfile - импортируем её и пишем простую функцию архивации:
Функция принимает на вход имя директории, файлы в которой нужно заархивировать и имя архива, который будет создан. Затем получает путь к архиву, список файлов для архивации и, открывая новый архив записывает в него каждый файл из списка в цикле, удаляя при этом файл, копия которого была помещена в архив. Возвращает путь к архиву.
Вызовем нашу функцию из кода скрипта:
Задаем имя архива и вызываем функцию. Затем выводим путь к заданному архиву. Готово! Мы достигли всех поставленных целей.
Заключение
Мы освоили базовую часть библиотеки os, но стоит понимать, что в ней есть еще много полезных функций, которые пригодятся при работе с сущностями операционной системы, познакомились с библиотекой zipfile, которая может создавать архивы. Но не успели освоить взаимодействие с командной строкой - уж слишком много материала для одной статьи. В другой раз обязательно исправим это.