В любом проекте разработки ПО нам приходится работать с файлами. При помощи Python можно осуществлять довольно много операций. Мы можем:
Наверняка можно делать что-то еще, но это те базовые операции, которые мы разберем в этой статье.
Чтобы сэкономить время и лучше изложить материал, я сгруппировал некоторые темы.
В этом разделе я покажу вам, что можно делать при помощи модуля os
в Python. Если вы гик вроде меня и хотите иметь возможность переименовывать файлы в соответствии с определенными правилами, Python вам поможет.
Для начала нам нужно получить список всех файлов. После этого мы будем выбирать файлы по одному и переименовывать.
[python_ad_block]Насколько я знаю, в модуле os
нет специального метода, который возвращал бы имена только файлов. Поэтому, получив список файлов и директорий, нам придется отсеять директории. Для этого мы можем воспользоваться методом os.path.isfile()
из модуля os
. Этот метод возвращает True, если аргумент является файлом. Аналогично, метод os.path.isdir()
возвращает True, если аргумент является директорией.
import os # returns name of all files & directory exist in current location files_dir = os.listdir('./blogs') print(files_dir) only_files = [] for i in files_dir: if os.path.isfile('./blogs/'+i): only_files.append(i) only_dir = [] for i in files_dir: if os.path.isdir('./blogs/'+i): only_dir.append(i) print('-'*15) print(only_files) # prints all files print('-'*15) print(only_dir) # prints all directories """ OUTPUT: ['1.txt', '2.txt', '3.txt', '4.txt', '5.txt', '6.txt', '7.txt', '8.txt', 'Test Directory 1', 'Test Directory 2'] --------------- ['1.txt', '2.txt', '3.txt', '4.txt', '5.txt', '6.txt', '7.txt', '8.txt'] --------------- ['Test Directory 1', 'Test Directory 2'] """
Итак, мы получили список всех файлов.
Чтобы переименовать файлы, мы воспользуемся методом rename()
и применим его к каждому файлу. Предположим, мы хотим добавить к файлам префиксы «Odd» (нечетный) и «Even» (четный), основываясь на индексах.
# only_files is a list of all files in the blogs directory for index, file_name in enumerate(only_files): if index % 2 == 0: os.rename('./blogs/'+file_name, './blogs/'+'Even-'+file_name) else: os.rename('./blogs/'+file_name, './blogs/'+'Odd-'+file_name)
Здесь метод enumerate()
возвращает номер по счетчику (начинается с 0) и значение из итератора (only_files
). Мы проверяем, является ли индекс (номер по счетчику) четным, и если да — добавляем префикс «Even» к имени файла. В противном случае добавляем префикс «Odd».
Подробнее о функции enumerate()
можно почитать в статье «Как работает функция enumerate() в Python?».
Вероятно, синтаксис метода os.rename()
вы поняли, но на всякий случай приведу его:
os.rename(текущее_имя, новое_имя)
При использовании этого метода имена (пути) можно писать как целиком, так и в относительном формате (главное — написать правильно). В нашем случае я написал «./blog/». Вторая косая черта указывает на вход внутрь директории blogs. Таким образом, путь к файлу превращается в «./blogs/1.txt».
Чтобы переместить файл, мы можем воспользоваться модулем os
или модулем shutil
. Я покажу перемещение файла при помощи метода rename()
из модуля os
.
Синтаксис rename()
тот же, только в качестве второго аргумента указывается путь к целевому файлу с именем самого файла.
os.rename(исходное_местонахождение, целевое_местонахождение)
Вероятно, это звучит запутано, но пример вам все объяснит:
import os os.rename('./blogs/1.txt', './blogs/Test Directory 1/1.txt') os.rename('./blogs/2.txt', './blogs/Test Directory 2/1.txt')
Итак, в первом методе rename мы берем файл 1.txt
из директории blogs
и перемещаем его в директорию Test Directory 1
, которая является поддиректорией blogs
.
Во втором сценарии мы берем файл 2.txt
и тоже перемещаем его в директорию Test Directory 1
, но с именем 1.txt
. Да, мы перемещаем и переименовываем файл одновременно. Если вы немного знакомы с командами Linux, вы могли заметить что работа метода os.rename()
напоминает работу команды mv
в Linux.
А как нам теперь удалить эти файлы?
Нам снова поможет модуль os
. Мы воспользуемся методом remove()
. Допустим, мы хотим удалить файл 3.txt
из директории blogs
. Для этого напишем следующий код:
import os os.remove('./blogs/3.txt')
Чтобы выполнить любую из операций чтения и записи, нам нужно сделать три основных шага:
Мы можем проделывать эти шаги, используя два паттерна. Объяснить их на словах сложно, так что я сделаю это при помощи кода.
# Открыть файл file = open('./blogs/1.txt', 'r', encoding="UTF-8") # Выполнить операцию data = file.read() print(data) # Закрыть файл file.close() """ OUTPUT: Python 101 Series """
Здесь мне нужно было открыть файл, выполнить операцию и закрыть файл вручную. Для открытия файла Python предоставляет метод open()
. Синтаксис:
open(файл, режим_доступа, кодировка)
Файл
— это местонахождение объекта файла. Режим_доступа
представляет режим, в котором мы хотим открыть файл. Вообще можно делать больше одной операции за раз, но об этом позже. Кодировка
представляет формат кодировки, в которой мы хотим работать с файлом. Этот параметр опционален. Чаще всего используется UTF-8.
Второй паттерн:
with open('./blogs/1.txt', 'r', encoding="UTF-8") as file: data = file.read() print(data)
Здесь мы используем паттерн контекстного менеджера. Если быть кратким, паттерн контекстного менеджера используется для разумного расходования ресурсов. Проблема первого паттерна в том, что мы можем забыть закрыть файл. В нашем примере это не слишком важно, но если вы оперируете тысячами или даже миллионами файлов, подобная ошибка повлияет на вашу систему. Паттерн контекстного менеджера освобождает ресурсы, как только мы покончили с задачей.
От редакции Pythonist. О контекстных менеджерах можно почитать в статье «Контекстные менеджеры в Python».
Итак, в первой строке мы открываем файл при помощи синтаксиса with open()
и присваиваем его переменной file
. Мы могли бы сделать то же самое, написав file = open()
. Преимущество нашего варианта в том, что Python автоматически освободит этот ресурс после третьей строки.
Поскольку после третьей строки мы окажемся вне контекста with open()
, все ресурсы, связанные с переменной file
, будут освобождены. Вы будете часто встречать паттерны контекстных менеджеров в коде для обработки файлов в продакшен-системах.
Помимо чтения, мы можем записывать файлы и дополнять их новыми данными. Делается это аналогично. То есть, чтобы записать данные в файл, мы пишем следующий код:
with open('./blogs/temp.txt', 'w', encoding="UTF-8") as file: data = "Python 101 Series" file.write(data)
Если файл с таким именем существует, он будет перезаписан новыми данными. А если такого файла нет, он будет создан и в него будут записаны данные. При этом следует учитывать, что создается только новый файл, директория создана не будет. Если я напишу open(«./blogs/temp/temp.txt», «w»), код выбросит ошибку, потому что внутри директории blogs
нет директории temp
.
Чтобы данные в файле не перезаписывались, а дополнялись, можно воспользоваться методом append
(в коде — аргумент 'a'
). Он добавляет данные в конец открытого файла.
with open('./blogs/temp.txt', 'a') as file: data = "\n New Python 101 Series" file.write(data)
В этом коде сперва Python проверит, существует ли файл temp.txt
, затем откроет его и добавит «\n New Python 101 Series» в конец файла. Если файл не существует, Python его создаст и запишет в него эту строку.
Я собрал базовые режимы доступа к файлам в таблице. Но есть и другие режимы, позволяющие оперировать бинарными данными и в бинарном формате. Полный список можно посмотреть в статье «File Access mode In Python».
Режим | Объяснение |
---|---|
r | чтение |
w | запись |
a | добавление в файл |
r+ | Чтение и запись данных в файл. Предыдущие данные в файле не удаляются. |
w+ | Запись и чтение данных. Существующие данные перезаписываются. |
a+ | Добавление и чтение данных из файла. Существующие данные не перезаписываются. |
В этой статье мы на простых примерах разобрали, как работать с файлами в Python. Я знаю, что запомнить все это за один раз сложно. Но это и не нужно: все придет с практикой, главное — разобраться.
Перевод статьи «File Handling in Python».
Управление памятью - важный, но часто упускаемый из виду аспект программирования. При неправильном подходе оно…
Как возникает круговой импорт? Эта ошибка импорта обычно возникает, когда два или более модуля, зависящих…
Вы когда-нибудь оказывались в ситуации, когда скрипт на Python выполняется очень долго и вы задаетесь…
В этом руководстве мы разберем все, что нужно знать о символах перехода на новую строку…
Блок if __name__ == "__main__" в Python позволяет определить код, который будет выполняться только при…
Давайте разберем, как настроить модульные тесты для экземпляров классов. Мы напишем тесты для проверки функциональности…