Как работать с файлами в Python

В любом проекте разработки ПО нам приходится работать с файлами. При помощи Python можно осуществлять довольно много операций. Мы можем:

  • выводить список файлов
  • перемещать и переименовывать файлы
  • удалять файлы
  • читать файлы
  • записывать в файлы
  • добавлять что-либо в файлы

Наверняка можно делать что-то еще, но это те базовые операции, которые мы разберем в этой статье.

Чтобы сэкономить время и лучше изложить материал, я сгруппировал некоторые темы.

Вывод списка файлов и их переименование

В этом разделе я покажу вам, что можно делать при помощи модуля os в Python. Если вы гик вроде меня и хотите иметь возможность переименовывать файлы в соответствии с определенными правилами, Python вам поможет.

Для начала нам нужно получить список всех файлов. После этого мы будем выбирать файлы по одному и переименовывать.

[python_ad_block]

Как получить список файлов в Python

Насколько я знаю, в модуле 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']
"""

Итак, мы получили список всех файлов.

Как переименовать файлы в Python

Чтобы переименовать файлы, мы воспользуемся методом 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».

Перемещение и удаление файлов в Python

Чтобы переместить файл, мы можем воспользоваться модулем 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')

Чтение файлов и запись в них

Чтобы выполнить любую из операций чтения и записи, нам нужно сделать три основных шага:

  1. Открыть файл
  2. Выполнить операцию
  3. Закрыть файл

Мы можем проделывать эти шаги, используя два паттерна. Объяснить их на словах сложно, так что я сделаю это при помощи кода.

# Открыть файл
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».

Прокрутить вверх