Как вывести размер файла python
Как получить расширение и размер файла в Python
Мы можем использовать функцию splitext() модуля os в Python, чтобы получить расширение файла. Эта функция разбивает путь к файлу на кортеж, имеющий два значения – корень и расширение.
Вот простая программа для получения расширения файла на Python.
Получение расширения файла с помощью модуля Pathlib
Мы также можем использовать модуль pathlib, чтобы получить расширение файла. Этот модуль был представлен в версии Python 3.4.
Всегда лучше использовать стандартные методы, чтобы получить расширение файла. Если вы уже используете модуль os, используйте метод splitext(). Для объектно-ориентированного подхода используйте модуль pathlib.
Получение размера файла
Мы можем получить размер файла в Python, используя модуль os.
Модуль os имеет функцию stat(), где мы можем передать имя файла в качестве аргумента. Эта функция возвращает структуру кортежа, содержащую информацию о файле. Затем мы можем получить его свойство st_size, чтобы получить размер файла в байтах.
Вот простая программа для печати размера файла в байтах и мегабайтах.
Если вы посмотрите на функцию stat(), мы можем передать еще два аргумента: dir_fd и follow_symlinks. Однако они не реализованы для Mac OS.
Вот обновленная программа, в которой я пытаюсь использовать относительный путь, но выдает NotImplementedError.
Операции с файлами
Базовые возможности языка программирования Python позволяют не только манипулировать данными в текстовых документах, но и всячески управлять ими самими. Для этого существует несколько специальных библиотек, встроенные функции которых обеспечивают копирование, удаление, переименование и прочие разновидности операций с файлами на компьютере.
Проверка существования файла
Избежать досадных ошибок при работе с текстовым документом, которые могут быть связаны с его отсутствием на жестком диске компьютера, поможет метод exists из модуля os. Его вызов позволяет проверить в Python существование файла по указанному пути, получив в качестве результирующего ответа булево значение True или False. Чтобы воспользоваться данным методом, необходимо прежде всего подключить библиотеку os, а затем вызвать exists у класса path. Следующий пример на Python показывает проверку наличия файлов test.txt и test10.txt в корневом каталоге жесткого диска D. Функция print показывает, что в наличии на D только первый документ.
Иногда при работе с документами возникает потребность в проверке не только существования некоего объекта по заданному пути. Функция isfile из уже упомянутой здесь библиотеки os дает программисту возможность убедиться в том, что полученный по определенному адресу объект на жестком диске компьютера является файлом, а не папкой. Данный метод также находится в классе path. В следующем примере показывается реакция isfile на получение в качестве аргумента файла test.txt и каталога folder в корне D. Как видно из результатов работы функции print, в первом случае отображается True, а затем False.
Проверить наличие файла по указанному адресу можно и с помощью функции open, применив дополнительно конструкцию with as. Данный метод производит открытие документа для того, чтобы программа могла взаимодействовать с его содержимым. Если функция open смогла без ошибок выполниться, это означает, что по переданному ей в качестве аргумента пути имеется файл. Если же произойдет исключение, то файл не удалось открыть. Это еще не говорит о том, что его нету. Возможно, к примеру, не достаточно прав доступа к нему. В приведенном ниже примере программа сообщает о наличии искомого документа при помощи метода print. Как видно из результатов, на экран выводится сообщение file is open.
Копирование файла
Библиотека под названием shutil включает в себя несколько полезных функций для создания копий объектов на жестком диске. Чтобы быстро скопировать файл в исходный каталог, стоит воспользоваться методом copyfile, предварительно подключив модуль shutil. В роли первого аргумента здесь выступает оригинальный документ, в то время как вторым параметром нужно поставить предполагаемый новый файл. Стоит учитывать, что копируется только содержимое, но не метаданные. В следующем примере происходит копирование данных из файла test.txt в test2.txt на диске D. Функция copyfile также возвращает адрес созданного документа.
Встроенный метод copy из модуля shutil позволяет в Python копировать файл в указанную папку, сохраняя при этом его изначальное имя. Приведенный ниже пример кода демонстрирует копирование информации из test.txt в объект, который находится на диске D в каталоге под названием folder. Как и в предыдущем случае с функцией copyfile, переносятся только внутренние данные, но не сведения о дате создания и редактирования документа.
Чтобы полностью скопировать информацию из текстового файла, а также все сведения о нем, необходимо воспользоваться готовым методом copy2. Способ его применения такой же, как и в случае с функцией copy. На месте первого параметра здесь размещается адрес изначального файла, в то время как второй аргумент сообщает локацию и название нового документа. Ниже показан пример, где содержимое и метаданные копируются в test2.txt из папки folder.
Удаление файла
Избавиться от объекта, если известно его имя и точное расположение на диске, очень легко. С этой задачей поможет справиться метод remove из уже упомянутой ранее библиотеки os. Все, что требуется сделать, это передать ей в качестве параметра полный адрес ненужного файла, не забыв для начала подключить модуль os. Ниже приведен пример того, как с помощью скрипта Python удалить файл test.txt в корне диска D.
Получение размера файла
Определить точный размер любого объекта на жестком диске можно с помощью стандартной функции getsize из модуля os, которая возвращает величину файла в байтах. Выполнив импорт библиотеки os, необходимо вызвать метод класса path. Аргументом тут выступает расположение документа в памяти компьютера. Согласно результатам выполнения getsize, размер test.txt составляет 7289. Метод print выводит это на экран.
Вычислить размер файла в Python можно и другим способом, открыв его при помощи open, после чего вызвав функцию seek. Ей необходимо передать в качестве параметра область для чтения данных, начиная от начала файла до его конца. В итоге следует вызвать метод tell через ссылку на текстовый файл, а затем отправить результат его работы в print для вывода в консоль.
Переименование файла
Изменить название документа можно не только благодаря средствам системы, но и с помощью готовых функций модуля os. С этой задачей хорошо справляется метод rename, принимающий в качестве параметров исходное и новое имя файла. Следующий пример показывает работу с документом test.txt в корневом каталоге диска D, который переименовывается в test1.txt.
Аналогично, можно в Python переименовать файл с помощью метода move из модуля shutil. Подключив данную библиотеку, достаточно лишь передать функции местоположение и новое имя документа. Код программы, где продемонстрировано переименование test.txt в test1.txt, находится ниже.
Таким образом, главные операции по взаимодействию с файлами в языке Python выполняются при помощи нескольких встроенных библиотек, в число которых входят os и shutil. Функции этих модулей позволяют осуществлять проверку на наличие файла на диске, копировать его в нескольких разных режимах, а также удалять, переименовывать и отображать размер.
8 команд для Python по работе с файлами и файловой системой, которые обязательно нужно знать
Python становится все популярнее благодаря относительной простоте изучения, универсальности и другим преимуществам. Правда, у начинающих разработчиков нередко возникают проблемы при работе с файлами и файловой системой. Просто потому, что они знают не все команды, которые нужно знать.
Эта статья предназначена как раз для начинающих разработчиков. В ней описаны 8 крайне важных команд для работы с файлами, папками и файловой системой в целом. Все примеры из этой статьи размещены в Google Colab Notebook (ссылка на ресурс — в конце статьи).
Показать текущий каталог
Самая простая и вместе с тем одна из самых важных команд для Python-разработчика. Она нужна потому, что чаще всего разработчики имеют дело с относительными путями. Но в некоторых случаях важно знать, где мы находимся.
Относительный путь хорош тем, что работает для всех пользователей, с любыми системами, количеством дисков и так далее.
Так вот, для того чтобы показать текущий каталог, нужна встроенная в Python OS-библиотека:
Ее легко запомнить, так что лучше выучить один раз, чем постоянно гуглить. Это здорово экономит время.
Имейте в виду, что я использую Google Colab, так что путь /content является абсолютным.
Проверяем, существует файл или каталог
Прежде чем задействовать команду по созданию файла или каталога, стоит убедиться, что аналогичных элементов нет. Это поможет избежать ряда ошибок при работе приложения, включая перезапись существующих элементов с данными.
Функция os.path.exists () принимает аргумент строкового типа, который может быть либо именем каталога, либо файлом.
В случае с Google Colab при каждом запуске создается папка sample_data. Давайте проверим, существует ли такой каталог. Для этого подойдет следующий код:
Эта же команда подходит и для работы с файлами:
Если папки или файла нет, команда возвращает false.
Объединение компонентов пути
В предыдущем примере я намеренно использовал слеш «/» для разделителя компонентов пути. В принципе это нормально, но не рекомендуется. Если вы хотите, чтобы ваше приложение было кроссплатформенным, такой вариант не подходит. Так, некоторые старые версии ОС Windows распознают только слеш «\» в качестве разделителя.
Но не переживайте, Python прекрасно решает эту проблему благодаря функции os.path.join (). Давайте перепишем вариант из примера в предыдущем пункте, используя эту функцию:
Создание директории
Ну а теперь самое время создать директорию с именем test_dir внутри рабочей директории. Для этого можно использовать функцию
os.mkdir():
Давайте посмотрим, как это работает на практике.
Если же мы попытаемся создать каталог, который уже существует, то получим исключение.
Именно поэтому рекомендуется всегда проверять наличие каталога с определенным названием перед созданием нового:
Вот что получается в результате.
Показываем содержимое директории
Еще одна полезная команда — os.listdir(). Она показывает все содержимое каталога.
Команда отличается от os.walk (), где последний рекурсивно показывает все, что находится «под» каталогом. os.listdir () намного проще в использовании, потому что просто возвращает список содержимого:
В некоторых случаях нужно что-то более продвинутое — например, поиск всех CSV-файлов в каталоге «sample_data». В этом случае самый простой способ — использовать встроенную библиотеку glob:
Перемещение файлов
Самое время попробовать переместить файлы из одной папки в другую. Рекомендованный способ — еще одна встроенная библиотека shutil.
Сейчас попробуем переместить все CSV-файлы из директории «sample_data» в директорию «test_dir». Ниже — пример кода для выполнения этой операции:
Кстати, есть два способа выполнить задуманное. Например, мы можем использовать библиотеку OS, если не хочется импортировать дополнительные библиотеки. Как os.rename, так и os.replace подходят для решения задачи.
Но обе они недостаточно «умные», чтобы позволить перемесить файлы в каталог.
Чтобы все это работало, нужно явно указать имя файла в месте назначения. Ниже — код, который это позволяет сделать:
Здесь функция os.path.basename () предназначена для извлечения имени файла из пути с любым количеством компонентов.
Другая функция, os.replace (), делает то же самое. Но разница в том, что os.replace () не зависит от платформы, тогда как os.rename () будет работать только в системе Unix / Linux.
Еще один минус — в том, что обе функции не поддерживают перемещение файлов из разных файловых систем, в отличие от shutil.
Поэтому я рекомендую использовать shutil.move () для перемещения файлов.
Копирование файлов
Аналогичным образом shutil подходит и для копирования файлов по уже упомянутым причинам.
Если нужно скопировать файл README.md из папки «sample_data» в папку «test_dir», поможет функция shutil.copy():
Удаление файлов и папок
Теперь пришел черед разобраться с процедурой удаления файлов и папок. Нам здесь снова поможет библиотека OS.
Когда нужно удалить файл, нужно воспользоваться командой os.remove():
Если требуется удалить каталог, на помощь приходит os.rmdir():
Однако он может удалить только пустой каталог. На приведенном выше скриншоте видим, что удалить можно лишь каталог level_3. Что если мы хотим рекурсивно удалить каталог level_1? В этом случае зовем на помощь shutil.
Функция shutil.rmtree() сделает все, что нужно:
Пользоваться ею нужно с осторожностью, поскольку она безвозвратно удаляет все содержимое каталога.
Собственно, на этом все. 8 важных операций по работе с файлами и каталогами в среде Python мы знаем. Что касается ссылки, о которой говорилось в анонсе, то вот она — это Google Colab Network с содержимым, готовым к запуску.
Понимаем, сколько памяти используют ваши объекты Python
Оказывается, нетривиально выяснить, сколько памяти фактически потребляется. В этой статье я расскажу о тонкостях управления памятью объекта Python и покажу, как точно измерить потребляемую память.
Также я запустил числа на 64-битном Python 2.7. В Python 3 числа иногда немного отличаются (особенно для строк, которые всегда являются Unicode), но концепции одинаковы.
Практическое исследование использования памяти Python
Во-первых, давайте немного разберемся и получим конкретное представление о фактическом использовании памяти объектами Python.
Встроенная функция sys.getsizeof()
Модуль sys стандартной библиотеки предоставляет функцию getsizeof(). Эта функция принимает объект (и необязательный параметр по умолчанию), вызывает метод sizeof() объекта и возвращает результат, поэтому вы также можете сделать ваши объекты инспектируемыми.
Измерение памяти объектов Python
Давайте начнем с некоторых числовых типов:
Интересно. Целое число занимает 24 байта.
Вот это да. 80 байтов! Это действительно заставляет задуматься о том, хотите ли вы представлять большое количество вещественных чисел как числа с плавающей запятой или десятичные дроби.
Давайте перейдем к строкам и коллекциям:
Хорошо. Пустая строка занимает 37 байтов, и каждый дополнительный символ добавляет еще один байт. Это многое говорит о компромиссе между сохранением нескольких коротких строк, когда вы будете платить 37 байтов за каждую, а не одну длинную строку, где вы платите только один раз.
Строки Unicode ведут себя аналогично, за исключением того, что служебные данные составляют 50 байтов, и каждый дополнительный символ добавляет 2 байта. Это стоит учитывать, если вы используете библиотеки, которые возвращают строки Unicode, но ваш текст может быть представлен в виде простых строк.
Кстати, в Python 3 строки всегда имеют Unicode, а служебные данные составляют 49 байт (они где-то сохранили байт). Объект байтов имеет служебную информацию только 33 байта. Если у вас есть программа, которая обрабатывает много коротких строк в памяти, и вы заботитесь о производительности, рассмотрите Python 3.
В чем дело? Пустой список занимает 72 байта, но каждый дополнительный int добавляет всего 8 байтов, где размер int составляет 24 байта. Список, который содержит длинную строку, занимает всего 80 байтов.
Ответ прост. Список не содержит сами объекты int. Он просто содержит 8-байтовый (в 64-битных версиях CPython) указатель на фактический объект int. Это означает, что функция getsizeof() не возвращает фактическую память списка и всех объектов, которые он содержит, а только память списка и указатели на свои объекты. В следующем разделе я представлю функцию deep_getsizeof(), которая решает эту проблему.
Наборы и словари якобы вообще не растут при добавлении элементов, но отмечают огромные накладные расходы.
Суть в том, что у объектов Python огромные фиксированные накладные расходы. Если ваша структура данных состоит из большого количества объектов коллекций, таких как строки, списки и словари, которые содержат небольшое количество элементов каждый, вы много платите.
Функция deep_getsizeof()
Теперь, когда я напугал вас до полусмерти и продемонстрировал, что sys.getsizeof() может только сказать вам, сколько памяти занимает примитивный объект, давайте посмотрим на более адекватное решение. Функция deep_getsizeof() рекурсивно выполняет детализацию и вычисляет фактическое использование памяти графом объектов Python.
У этой функции есть несколько интересных аспектов. Она учитывает объекты, на которые ссылаются несколько раз, и учитывает их только один раз, отслеживая идентификаторы объектов. Другая интересная особенность реализации заключается в том, что она в полной мере использует абстрактные базовые классы модуля коллекций. Это позволяет функции очень лаконично обрабатывать любую коллекцию, которая реализует базовые классы Mapping или Container, вместо непосредственного обращения к множеству типов коллекций, таких как: строка, Unicode, байты, список, кортеж, dict, frozendict, OrderedDict, set, frozenset и т.д.
Давайте посмотрим на это в действии:
Строка длиной 7 занимает 44 байта (37 служебных данных + 7 байтов для каждого символа).
Пустой список занимает 72 байта (только накладные расходы).
python deep_getsizeof ([x], set ()) 124
Список, содержащий строку x, занимает 124 байта (72 + 8 + 44).
Список, содержащий строку x 5 раз, занимает 156 байтов (72 + 5 * 8 + 44).
Последний пример показывает, что deep_getsizeof() подсчитывает ссылки на один и тот же объект (строку x) только один раз, но подсчитывается указатель каждой ссылки.
Баг или фича
Оказывается, что у CPython есть несколько хитростей, поэтому числа, которые вы получаете от deep_getsizeof(), не полностью отражают использование памяти программой Python.
Подсчет ссылок
Python управляет памятью, используя семантику подсчета ссылок. Когда на объект больше не ссылаются, его память освобождается. Но пока есть ссылка, объект не будет освобожден. Такие вещи, как циклические ссылки, могут вас сильно укусить.
Маленькие объекты
CPython управляет небольшими объектами (менее 256 байтов) в специальных пулах на 8-байтовых границах. Есть пулы для 1-8 байтов, 9-16 байтов и вплоть до 249-256 байтов. Когда объект размером 10 выделяется, он выделяется из 16-байтового пула для объектов размером 9-16 байт. Таким образом, хотя он содержит только 10 байтов данных, он будет стоить 16 байтов памяти. Если вы выделяете 1 000 000 объектов размером 10, вы фактически используете 16 000 000 байтов, а не 10 000 000 байтов, как вы можете предположить. Эти 60% накладных расходов явно не тривиальны.
Целые числа
CPython хранит глобальный список всех целых чисел в диапазоне [-5, 256]. Эта стратегия оптимизации имеет смысл, потому что маленькие целые числа всплывают повсюду, и, учитывая, что каждое целое число занимает 24 байта, оно экономит много памяти для типичной программы.
Это также означает, что CPython предварительно выделяет 266 * 24 = 6384 байта для всех этих целых чисел, даже если вы не используете большинство из них. Вы можете проверить это с помощью функции id(), которая дает указатель на фактический объект. Если вы называете id(x) несколько для любого x в диапазоне [-5, 256], вы будете каждый раз получать один и тот же результат (для одного и того же целого числа). Но если вы попробуете это для целых чисел за пределами этого диапазона, каждый из них будет отличаться (новый объект создается на лету каждый раз).
Вот несколько примеров в этом диапазоне:
Вот несколько примеров за пределами диапазона:
Память Python против системной памяти
CPython является своего рода притяжательным. Во многих случаях, когда на объекты памяти в вашей программе больше не ссылаются, они не возвращаются в систему (например, маленькие объекты). Это хорошо для вашей программы, если вы выделяете и освобождаете много объектов (которые принадлежат одному и тому же 8-байтовому пулу), потому что Python не должен беспокоить систему, что относительно дорого. Но это не так здорово, если ваша программа обычно использует X байтов и при некоторых временных условиях она использует в 100 раз больше (например, анализирует и обрабатывает большой файл конфигурации только при запуске).
Теперь эта память 100X может быть бесполезно захвачена в вашей программе, никогда больше не использоваться и лишать систему возможности выделять ее другим программам. Ирония заключается в том, что если вы используете модуль обработки для запуска нескольких экземпляров вашей программы, вы строго ограничите количество экземпляров, которые вы можете запустить на данном компьютере.
Профилировщик памяти
Чтобы измерить и измерить фактическое использование памяти вашей программой, вы можете использовать модуль memory_profiler. Я немного поиграл с этим, и я не уверен, что доверяю результатам. Он очень прост в использовании. Вы декорируете функцию (может быть главной (0 функция)) с помощью декоратора @profiler, и когда программа завершает работу, профилировщик памяти выводит на стандартный вывод удобный отчет, который показывает общее количество и изменения в памяти для каждой строки. Вот пример программы, которую я запускал под профилировщиком:
Заключение
CPython использует много памяти для своих объектов. Он использует различные приемы и оптимизации для управления памятью. Отслеживая использование памяти вашим объектом и зная модель управления памятью, вы можете значительно уменьшить объем памяти вашей программы.
Работа с файлами в Python
В Python есть несколько встроенных модулей и функций для работы с файлами. Эти функции распределены по нескольким модулям, таким как os, os.path, shutil и pathlib, и это всего лишь некоторые из них. В этом уроке собраны в одном месте многие функции, которые вам необходимо знать для выполнения наиболее распространенных операций с файлами в Python.
В этом уроке вы узнаете, как:
Содержание
Шаблон Python «with open(…) as …» ↑
Чтение и запись данных в файлы с помощью Python довольно просты. Для этого необходимо сначала открыть файлы в соответствующем режиме. Вот пример того, как использовать шаблон Python «with open (…) as…» для открытия текстового файла и чтения его содержимого:
open() принимает в качестве аргументов имя файла и режим. r открывает файл в режиме только для чтения. Чтобы записать данные в файл, вместо этого передайте w в качестве аргумента:
В приведенных выше примерах open() открывает файлы для чтения или записи и возвращает дескриптор файла (в данном случае f ), который предоставляет методы, которые можно использовать для чтения или записи данных в файл. Ознакомьтесь с разделами Чтение и запись файлов в Python и Working With File I/O in Python для получения дополнительной информации о том, как читать и записывать файлы.
Получение списка каталогов ↑
Предположим, в вашем текущем рабочем каталоге есть подкаталог my_directory со следующим содержимым:
Встроенный модуль os имеет ряд полезных функций, которые можно использовать для вывода списка содержимого каталогов и фильтрации результатов. Чтобы получить список всех файлов и папок в определенном каталоге файловой системы, используйте os.listdir() в устаревших версиях Python или os.scandir() в Python 3.x. os.scandir() — предпочтительный метод для использования, если вы также хотите получить свойства файла и каталога, такие как размер файла и дату модификации.
Список каталогов в устаревших версиях Python ↑
В версиях Python до Python 3 для получения списка каталого используетсяв метод os.listdir() :
os.listdir() возвращает список Python, содержащий имена файлов и подкаталогов в каталоге, заданном аргументом пути:
Такой список каталогов нелегко прочитать. Распечатка вывода вызова os.listdir() с использованием цикла помогает очистить ситуацию:
Список каталогов в современных версиях Python ↑
os.scandir() был представлен в Python 3.5 и задокументирован в PEP 471. os.scandir() возвращает итератор, а не список при вызове:
ScandirIterator указывает на все записи в текущем каталоге. Вы можете перебрать содержимое итератора и распечатать имена файлов:
Другой способ получить список каталогов — использовать модуль pathlib:
Выполнение приведенного выше кода приводит к следующему:
Использование pathlib.Path() или os.scandir() вместо os.listdir() является предпочтительным способом получения списка каталогов, особенно когда вы работаете с кодом, которому требуется информация о типе файла и атрибутах файла. pathlib.Path() предлагает большую часть функций обработки файлов и путей, которые есть в os и shutil, и его методы более эффективны, чем некоторые из этих модулей. Вскоре мы обсудим, как получить свойства файла.
Вот еще раз функции листинга каталогов:
| Функция | Описание |
|---|---|
| os.listdir() | Возвращает список всех файлов и папок в каталоге |
| os.scandir() | Возвращает итератор всех объектов в каталоге, включая информацию об атрибутах файла |
| pathlib.Path.iterdir() | Возвращает итератор всех объектов в каталоге, включая информацию об атрибутах файла |
Эти функции возвращают список всего в каталоге, включая подкаталоги. Это не всегда может быть тем поведением, которое вам нужно. В следующем разделе будет показано, как отфильтровать результаты из списка каталогов.
Список всех файлов в каталоге ↑
Более простой способ перечислить файлы в каталоге — использовать os.scandir() или pathlib.Path() :
Вот как вывести список файлов в каталоге с помощью pathlib.Path() :
Приведенный выше код можно сделать более кратким, если объединить цикл for и оператор if в одно выражение генератора.
Модифицированная версия выглядит так:
Список подкаталогов ↑
Чтобы вывести список подкаталогов вместо файлов, используйте один из следующих способов. Вот как использовать os.listdir() и os.path() :
Вот как использовать os.scandir() :
Вот как использовать pathlib.Path() :
Получение атрибутов файла ↑
os.scandir() и pathlib.Path() получают список каталогов с объединенными атрибутами файлов. Это может быть потенциально более эффективным, чем использование os.listdir() для вывода списка файлов и последующего получения информации об атрибутах для каждого файла.
В приведенных ниже примерах показано, как получить время последнего изменения файлов в my_directory/. Вывод в секундах:
В модуле pathlib есть соответствующие методы для получения информации о файлах, которые дают те же результаты:
Вместе эти директивы производят вывод, который выглядит следующим образом:
Синтаксис преобразования даты и времени в строки может сбивать с толку. Чтобы узнать больше об этом, ознакомьтесь с официальной документацией по нему. Еще одна удобная ссылка, которую легко запомнить, — это http://strftime.org/.
Создание каталогов ↑
Рано или поздно программы, которые вы пишете, должны будут создавать каталоги, чтобы хранить в них данные. os и pathlib включают функции для создания каталогов. Мы рассмотрим это:
| Функция | Описание |
|---|---|
| os.mkdir() | Создает единственный подкаталог |
| pathlib.Path.mkdir() | Создает один или несколько каталогов |
| os.makedirs() | Создает несколько каталогов, включая промежуточные каталоги |
Создание единого каталога ↑
Чтобы создать единый каталог, передайте путь к каталогу в качестве параметра функции os.mkdir() :
Если путь уже существует, mkdir() вызывает FileExistsError :
Чтобы избежать подобных ошибок, перехватывайте ошибку, когда она возникает, и дайте знать своему пользователю:
Это не вызовет ошибки, если каталог уже существует.
Создание нескольких каталогов ↑
В результате получите вложенную структуру каталогов, содержащую папки 2018, 10 и 05:
Передача parent = True в Path.mkdir() заставляет его создавать каталог 05 и все родительские каталоги, необходимые для того, чтобы путь был действительным.
Выполнение приведенного выше кода создает структуру каталогов, подобную приведенной ниже, за один раз:
Я предпочитаю использовать pathlib при создании каталогов, так как можно использовать ту же функцию для создания одиночных или вложенных каталогов.
Сопоставление имени файла с шаблоном ↑
Использование строковых методов ↑
Получив список файлов в каталоге одним из описанных выше методов, вы, скорее всего, захотите найти файлы, соответствующие определенному шаблону.
Вам доступны следующие методы и функции:
Каждый из них обсуждается ниже. Примеры в этом разделе будут выполняться в каталоге с именем some_directory, который имеет следующую структуру:
Если вы используете оболочку Bash, вы можете создать указанную выше структуру каталогов с помощью следующих команд:
Использование строковых методов ↑
Простое сопоставление с шаблоном имени файла с помощью fnmatch ↑
Более расширенное сопоставление с шаблоном ↑
Сопоставление с шаблоном имени файла с помощью glob ↑
Еще один полезный модуль для сопоставления с образцом — glob.
Например, ввод mv *.py python_files/ в оболочке UNIX перемещает (mv) все файлы с расширением .py из текущего каталога в каталог python_files. Символ * — это подстановочный знак, означающий «любое количество символов», а *.py — шаблон glob. Эта возможность оболочки недоступна в операционной системе Windows. Модуль glob добавляет эту возможность в Python, что позволяет программам Windows использовать эту функцию.
Вот пример того, как использовать glob для поиска всех исходных файлов Python (.py) в текущем каталоге:
glob.glob (‘*. py’) ищет все файлы с расширением .py в текущем каталоге и возвращает их в виде списка. glob также поддерживает подстановочные знаки в стиле оболочки для соответствия шаблонам:
Это найдет все текстовые файлы (.txt), которые содержат цифры в имени файла:
glob также упрощает рекурсивный поиск файлов в подкаталогах:
Вызов p.glob(‘*.P*’) возвращает объект-генератор, который указывает на все файлы в текущем каталоге, которые начинаются с буквы p в их расширении.
Напомним, вот таблица функций, которые мы рассмотрели в этом разделе:
| Функция | Описание |
|---|---|
| startswith() | Проверяет, начинается ли строка с указанного шаблона и возвращает True или False |
| endswith() | Проверяет, заканчивается ли строка указанным шаблоном и возвращает True или False |
| fnmatch.fnmatch(имя файла, шаблон) | Проверяет, соответствует ли имя файла шаблону и возвращает True или False |
| glob.glob() | Возвращает список имен файлов, соответствующих шаблону |
| pathlib.Path.glob() | Находит шаблоны в именах путей и возвращает объект-генератор |
Просмотр каталогов и обработка файлов ↑
os.walk() по умолчанию перемещается по каталогам сверху вниз:
os.walk() возвращает три значения на каждой итерации цикла:
На каждой итерации он распечатывает имена найденных подкаталогов и файлов:
Чтобы пройти по дереву каталогов снизу вверх, передайте аргумент ключевого слова topdown = False в os.walk() :
Передача аргумента topdown = False заставит os.walk() сначала распечатать файлы, которые она находит в подкаталогах:
Создание временных файлов и каталогов ↑
Python предоставляет удобный модуль для создания временных файлов и каталогов, называемый tempfile.
tempfile можно использовать для временного открытия и хранения данных в файле или каталоге во время работы вашей программы. tempfile обрабатывает удаление временных файлов, когда ваша программа завершает работу с ними.
Вот как создать временный файл:
Временные файлы и каталоги, созданные с помощью tempfile, хранятся в специальном системном каталоге для хранения временных файлов. Python ищет в стандартном списке каталогов тот, в котором пользователь может создавать файлы.
В Windows каталоги — C:\TEMP, C:\TMP, \TEMP и \TMP в указанном порядке. На всех других платформах это каталоги /tmp, /var/tmp и /usr/tmp в указанном порядке. В крайнем случае, tempfile сохранит временные файлы и каталоги в текущем каталоге.
Создаётся временный файл и считывает из него данные. Как только содержимое файла считывается, временный файл закрывается и удаляется из файловой системы.
tempfile также можно использовать для создания временных каталогов. Давайте посмотрим, как это можно сделать с помощью tempfile.TemporaryDirectory() :
Удаление файлов и каталогов ↑
Вы можете удалять отдельные файлы, каталоги и целые деревья каталогов, используя методы, найденные в модулях os, shutil и pathlib. В следующих разделах описывается, как удалить файлы и каталоги, которые вам больше не нужны.
Удаление файлов в Python ↑
Удаление файла с помощью os.unlink() аналогично тому, как вы это делаете с помощью os.remove() :
В следующем примере показано, как использовать обработку исключений для обработки ошибок при удалении файлов:
Наконец, можно использовать pathlib.Path.unlink() для удаления файлов:
Удаление каталогов ↑
Стандартная библиотека предлагает следующие функции для удаления каталогов:
В качестве альтернативы вы можете использовать pathlib для удаления каталогов:
Удаление всех деревьев каталогов ↑
Чтобы удалить непустые каталоги и целые деревья каталогов, Python предлагает shutil.rmtree() :
Здесь просматривается дерево каталогов и делается попытка удалить каждый найденный каталог. Если каталог не пустой, возникает ошибка OSError и этот каталог пропускается. В таблице ниже перечислены функции, рассматриваемые в этом разделе:
| Функция | Описание |
|---|---|
| os.remove() | Удаляет файл и не удаляет каталоги |
| os.unlink() | Идентичен os.remove() и удаляет один файл |
| pathlib.Path.unlink() | Удаляет файл и не может удалять каталоги |
| os.rmdir() | Удаляет пустой каталог |
| pathlib.Path.rmdir() | Удаляет пустой каталог |
| shutil.rmtree() | Удаляет все дерево каталогов и может использоваться для удаления непустых каталогов |
Копирование, перемещение и переименование файлов и каталогов ↑
Python поставляется с модулем shutil. shutil — это сокращение от short for shell utilities (служебных программ оболочки). Он обеспечивает ряд высокоуровневых операций с файлами для поддержки копирования, архивирования и удаления файлов и каталогов. В этом разделе вы узнаете, как перемещать и копировать файлы и каталоги.
Копирование файлов в Python ↑
Чтобы сохранить все метаданные файла при копировании, используйте shutil.copy2() :
Копирование каталогов ↑
В то время как shutil.copy() копирует только один файл, shutil.copytree() копирует весь каталог и все, что в нем содержится. shutil.copytree (src, dest) принимает два аргумента: исходный каталог и целевой каталог, в который будут скопированы файлы и папки. Вот пример того, как скопировать содержимое одной папки в другое место:
Перемещение файлов и каталогов ↑
src — это файл или каталог, который нужно переместить, а dst — это место назначения:
Переименование файлов и каталогов ↑
В Python есть функция os.rename (src, dst) для переименования файлов и каталогов:
Другой способ переименовать файлы или каталоги — использовать rename() из модуля pathlib:
Архивирование ↑
Архивы — это удобный способ упаковать несколько файлов в один. Двумя наиболее распространенными типами архивов являются ZIP и TAR. Написанные вами программы Python могут создавать, читать и извлекать данные из архивов. В этом разделе вы узнаете, как читать и писать в оба формата архивов.
Чтение ZIP-файлов ↑
Чтобы получить список файлов в архиве, вызовите namelist() объекта ZipFile :
В следующем примере показано, как получить более подробную информацию об архивных файлах в Python REPL. Предположим, что модуль zipfile уже импортирован, а bar_info — это тот же объект, который вы создали в предыдущих примерах:
bar_info содержит подробную информацию о bar.py, такую как его размер при сжатии и полный путь.
В первой строке показано, как получить дату последнего изменения файла. В следующей строке показано, как получить размер файла после сжатия. Последняя строка показывает полный путь к bar.py в архиве.
Извлечение ZIP-архивов ↑
Эти методы по умолчанию извлекают файлы в текущий каталог. Оба они принимают необязательный параметр пути, который позволяет указать другой каталог для извлечения файлов. Если каталог не существует, то он создается автоматически. Чтобы извлечь файлы из архива, выполните следующие действия:
Извлечение данных из архивов, защищенных паролем ↑
Создание новых ZIP-архивов ↑
Чтобы создать новый ZIP-архив, вы открываете объект ZipFile в режиме записи ( w ) и добавляете файлы, которые хотите заархивировать:
В этом примере new_zip открывается в режиме записи, и каждый файл в file_list добавляется в архив. Когда набор операторов with завершается, new_zip закрывается. Открытие ZIP-файла в режиме записи стирает содержимое архива и создает новый архив.
Чтобы добавить файлы в существующий архив, откройте объект ZipFile в режиме добавления, а затем добавьте файлы:
Здесь вы открываете архив new.zip, созданный в предыдущем примере, в режиме добавления. Открытие объекта ZipFile в режиме добавления позволяет добавлять новые файлы в ZIP-файл, не удаляя его текущее содержимое. После добавления файлов в ZIP-файл оператор with выходит из контекста и закрывает ZIP-файл.
Открытие архивов TAR ↑
Файлы TAR представляют собой несжатые файловые архивы, такие как ZIP. Их можно сжать с помощью методов сжатия gzip, bzip2 и lzma. Класс TarFile позволяет читать и записывать архивы TAR.
Сделайте это, чтобы прочитать из архива:
| Режим | Действие |
|---|---|
| r | Открывает архив для чтения с прозрачным сжатием |
| r:gz | Открывает архив для чтения со сжатием gzip |
| r:bz2 | Открывает архив для чтения со сжатием bzip2 |
| r:xz | Открывает архив для чтения со сжатием lzma |
| w | Открывает архив для записи без сжатия |
| w:gz | Открывает архив для записи в сжатом формате gzip |
| w:xz | Открывает архив для записи в сжатом формате lzma |
| а | Открывает архив для добавления без сжатия |
Возвращается список с именами содержимого архива.
Примечание. Чтобы показать вам, как использовать различные методы объекта tarfile, файл TAR в примерах открывается и закрывается вручную в интерактивном сеансе REPL.
Такое взаимодействие с файлом TAR позволяет увидеть результат выполнения каждой команды. Обычно вы хотите использовать диспетчер контекста для открытия файловых объектов.
К метаданным каждой записи в архиве можно получить доступ с помощью специальных атрибутов:
Извлечение файлов из архива TAR ↑
В этом разделе вы узнаете, как извлекать файлы из архивов TAR, используя следующие методы:
.extractall() имеет необязательный аргумент пути, чтобы указать, куда должны идти извлеченные файлы. Здесь архив распаковывается в распакованный каталог. Следующие команды показывают, что архив был успешно извлечен:
Создание новых архивов TAR ↑
Вот как это сделать:
Сначала составляется список файлов, которые нужно добавить в архив, чтобы не приходилось добавлять каждый файл вручную.
В следующей строке с помощью диспетчера контекста открывается новый архив с именем packages.tar в режиме записи. Открытие архива в режиме записи ( ‘w’ ) позволяет вам записывать в архив новые файлы.Все существующие файлы в архиве удаляются и создается новый архив.
После того, как архив создан и заполнен, менеджер контекста с автоматически закрывает его и сохраняет в файловой системе. Последние три строки открывают только что созданный архив и распечатывают имена содержащихся в нем файлов. Чтобы добавить новые файлы в существующий архив, откройте архив в режиме добавления ( ‘a’ ):
Открытие архива в режиме добавления позволяет добавлять в него новые файлы, не удаляя уже существующие.
Работа со сжатыми архивами ↑
Например, для чтения или записи данных в архив TAR, сжатый с помощью gzip, используйте режимы ‘r:gz’ или ‘w:gz’ соответственно:
Режим ‘w:gz’ открывает архив для записи, сжатой gzip, а ‘r:gz’ открывает архив для чтения сжатого gzip. Открытие сжатых архивов в режиме добавления невозможно. Чтобы добавить файлы в сжатый архив, вам необходимо создать новый архив.
Более простой способ создания архивов ↑
Стандартная библиотека Python также поддерживает создание архивов TAR и ZIP с использованием высокоуровневых методов в модуле shutil. Утилиты архивирования в shutil позволяют создавать, читать и извлекать архивы ZIP и TAR. Эти утилиты полагаются на модули tarfile и zipfile нижнего уровня.
Работа с архивами с помощью shutil.make_archive()
shutil.make_archive() принимает как минимум два аргумента: имя архива и формат архива.
Вот как создать архив TAR с помощью shutil:
Чтение нескольких файлов ↑
Python поддерживает чтение данных из нескольких входных потоков или из списка файлов через модуль fileinput. Этот модуль позволяет быстро и легко перебирать содержимое одного или нескольких текстовых файлов. Вот типичный способ использования файлового ввода:
Использование fileinput для перебора нескольких файлов
Давайте воспользуемся fileinput, чтобы создать грубую версию общей утилиты UNIX cat. Утилита cat последовательно читает файлы, записывая их на стандартный вывод. Если в аргументах командной строки указано несколько файлов, cat объединит текстовые файлы и отобразит результат в терминале:
Выполнение этого в двух текстовых файлах в моем текущем каталоге дает следующий результат:
Заключение ↑
Теперь вы знаете, как использовать Python для выполнения наиболее распространенных операций с файлами и группами файлов. Вы узнали о различных встроенных модулях, используемых для чтения, поиска и управления ими.
Теперь вы готовы использовать Python для:
Опубликовано Вадим В. Костерин
ст. преп. кафедры ЦЭиИТ. Автор более 130 научных и учебно-методических работ. Лауреат ВДНХ (серебряная медаль). Посмотреть больше записей


