Работа с файлами в Python

В этой статье мы расскажем, как в Python осуществляется чтение файла. Мы будем рассматривать текстовые форматы, JSON и двоичные файлы. Заодно разберем и запись информации в файл.

Скачивайте книги ТОЛЬКО на русском языке у нас в телеграм канале: PythonBooksRU

Содержание

Плоские и неплоские файлы

Специалисты по Data Science, и не только, ежедневно обрабатывают большое количество данных. Эти данные могут поступать из разных источников, например из баз данных, из Excel, из плоских файлов, с публичных сайтов, таких как kaggle. Формат файлов с данными тоже может быть любым, например .csv, .txt, .parquet и т. д.

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

Но прежде чем перейти к операциям с файлами в Python, давайте познакомимся с понятием плоского файла.

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

Имя,Фамилия,Возраст,Город
Алексей,Иванов,25,Москва
Елена,Смирнова,30,Санкт-Петербург
Иван,Петров,35,Казань

И в плоских, и в неплоских файлах данные обычно представлены в виде таблиц “строка-столбец”.

Неплоский файл – это файл, в котором каждой записи присваивается индекс. По индексу записи можно узнать ее точное местоположение. Чтение файла такого типа обычно осуществляется при помощи специального приложения, например, системы управления базами данных.

XML является примером неплоского файла.

Плоский файл может быть обычным текстовым файлом в формате TSV или CSV, а может быть и двоичным файлом. В первом случае файлы обычно содержат по одной записи в строке.

Файлы CSV содержат значения, разделенные запятыми, например:

NAME,ADDRESS,EMAIL
ABC,CITY A,abc@xyz.com
LMN,CITY B,lmn@xyz.com
PQR,CITY C,pqr@xyz.com

Помимо запятых, значения в файлах могут быть разделены указанными пользователем разделителями. Это может быть, например, табуляция \t или какой-нибудь символ (#, &, ||):

NAME||ADDRESS||EMAIL
ABC||CITY A||abc@xyz.com
LMN||CITY B||lmn@xyz.com
PQR||CITY C||pqr@xyz.com

Давайте теперь разберемся, как Python создает и читает эти форматы файлов.

Файловые объекты Python

В Python есть встроенные функции для создания, чтения, записи и манипулирования доступными файлами.

В Python есть модуль для доступа к файлам. Это модуль io, и его можно использовать даже не импортируя.

Прежде чем читать файл, записывать в него данные или осуществлять еще какие-то манипуляции с ним, необходимо его открыть. Для этого нужно воспользоваться функцией open(filename, access_mode), которая возвращает файловый объект.

После этого вы можете просто использовать этот файловый объект для чтения из файла или записи в него. Как и все остальное, файлы в Python также реализованы как объекты, имеющие свои собственные атрибуты и методы.

Если при открытии файла происходит сбой операции, возникает исключение IOError. Это может произойти по разным причинам, например, при попытке чтения файла, открытого в режиме записи, или при обращении к файлу, который уже закрыт.

Глобально существует два типа плоских файлов: текстовые и двоичные. Текстовые файлы имеют символ конца строки (End-Of-Line, EOL) для обозначения ее конца. В Python символ новой строки (\n) является значением EOL по умолчанию. Поскольку двоичные файлы хранят данные после их преобразования в код из нулей и единиц, символ EOL в них отсутствует.

Давайте теперь на примерах разберем файловые объекты Python.

Функция open()

Встроенная функция Python open() имеет следующий синтаксис:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

Как видите, функция open() имеет 8 параметров и значения по умолчанию почти для каждого.

Сейчас мы сосредоточимся на первом и втором параметрах, которые необходимы для чтения и записи файлов. Остальные параметры будут рассматриваться постепенно, по мере продвижения.

Давайте разберемся с первым аргументом, то есть с файлом.

Параметр file функции open()

file – это обязательный аргумент, который вы должны предоставить функции open(). Остальные аргументы являются необязательными: если их не указать, то будут использоваться их значения по умолчанию.

Аргумент file представляет собой тот файл, который вы хотите открыть. А если выразиться более точно, то это путь к местонахождению файла в вашей системе.

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

my_file_handle=open("mynewtextfile.txt") 

Убедитесь, что имя файла и путь к нему указаны правильно, иначе вы получите ошибку FileNotFoundError:

my_file_handle=open("folder/test.txt") my_file_handle.read()
---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

<ipython-input-2-a0d1ea891918> in <module>
----> 1 my_file_handle=open("folder/test.txt")
      2 my_file_handle.read()


FileNotFoundError: [Errno 2] No such file or directory: 'folder/test.txt'

Обработка исключений в файлах

Вы можете перехватить исключение с помощью блока try-finally:

try:
    my_file_handle=open("folder/test.txt")
except IOError:
    print("File not found or path is incorrect")
finally:
    print("exit")
File not found or path is incorrect
exit

А теперь давайте разберемся со вторым аргументом функции open(), то есть с режимами доступа.

Примечание редакции: о применении блоков try-except-finally читайте в статье “Как обрабатывать исключения в Python”.

Параметр mode функции open()

Этот параметр определяет режим доступа к файлу. Он указывает, что именно можно будет делать с открытым файлом в дальнейшем. Например, вы можете открыть файл:

  • только для чтения
  • только для записи
  • для добавления данных
  • для чтения и записи.

Хотя режимов доступа довольно много, наиболее часто используются режимы чтения и записи.

Для чтения файла используется режим 'r'. Он является режимом по умолчанию, то есть его можно не указывать явно. В других случаях, когда вы хотите записать файл или добавить в него данные, нужно обязательно указать соответствующий режим ('w' или 'a').

Конечно, режимов доступа есть куда больше! Взгляните на следующую таблицу:

СимволЗначение
rОткрыть файл только для чтения. Чтение начинается с начала файла. Это режим по умолчанию.
rbОткрыть файл только для чтения в двоичном формате. Чтение начинается с начала файла.
r+Открыть файл для чтения и записи. Указатель файла помещается в начало файла.
WОткрыть файл только для записи. Указатель файла помещается в начало файла. Существующий файл перезаписывается, а новый создается, если его не существует.
wbТо же, что и ‘W’, но в двоичном режиме.
w+То же, что и ‘W’, но также позволяет читать из файла.
wb+То же, что и ‘wb’, но также позволяет читать из файла.
aОткрыть файл для добавления. Запись начинается в конце файла. Если файл не существует, создается новый файл.
abТо же, что и ‘a’, но в двоичном режиме. Создается новый файл, если файл не существует.
atТо же, что и ‘a’, но также открыт для чтения.
ab+То же, что и ‘ab’, но также открыт для чтения.

Как вы уже знаете, существует два типа плоских файлов. Именно поэтому есть возможность указать, какой формат вы хотите открыть: текстовый или двоичный. Конечно, по умолчанию используется первый. Добавляя 'b' к режимам доступа, вы указываете, что хотите работать с файлом в двоичном формате.

Чтение файла

Давайте попробуем все способы чтения из файла, чтобы разобраться с режимами доступа. Существует три способа чтения из файла:

  • read([n])
  • readline([n])
  • readlines()

Здесь n – это количество байт, которые нужно прочитать. Если в n ничего не передано, то считается, что считать нужно весь файл.

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

my_file=open("test1.txt","r")
print(my_file.read())

Результат:

1st line
2nd line
3rd line
4th line
5th line

Метод read() просто выводит весь файл, если в аргументе не указано количество байт. Если вы выполните my_file.read(3), то получите первые три символа файла:

my_file=open("test1.txt","r")
print(my_file.read(3))


# Результат:
# 1st

Функция readline(n) выводит не более n байт одной строки файла. Если ей не передать аргумент, она считает ровно одну строку.

my_file.close()
my_file=open("test1.txt","r")
# Вывод одной строки
print(my_file.readline())
# Вывод двух символов следующей строки
print(my_file.readline(2))

Результаты:

1st line

2n

Метод readlines() возвращает список всех строк в файле, который можно перебрать с помощью цикла for:

my_file=open("test1.txt","r")
my_file.readlines()


# Результат:
# ['1st line\n', '2nd line\n', '3rd line\n', '4th line\n', '5th line']

Закрытие файлов Python

Для закрытия файла используется метод close(). Когда вы используете этот метод, вы очищаете весь буфер и закрываете файл.

my_file.close()

Пример построчного чтения файла с применением цикла for и последующим закрытием файла:

my_file=open("test1.txt","r")

for line in my_file:
    print(line)

my_file.close()

Результат:

1st line

2nd line

3rd line

4th line

5th line

Запись в файл в Python

Для записи в файл в Python можно использовать два метода:

  • write(string) для текста или write(byte_string) для двоичного кода
  • writelines(list)

Давайте создадим новый файл. Следующая команда создаст новый файл в указанной папке, поскольку он не существует. Не забудьте указать правильный путь с правильным именем файла, иначе вы получите ошибку:

new_file=open("newfile.txt",mode="w",encoding="utf-8")

new_file.write("Writing to a new file\n")
new_file.write("Writing to a new file\n")
new_file.write("Writing to a new file\n")
new_file.close()

Режим добавления

Теперь давайте запишем список в этот файл в режиме a+. Этот режим позволяет не перезаписывать файл, а добавить одержимое в конец файла:

fruits=["Orange\n","Banana\n","Apple\n"]
new_file=open("newfile.txt",mode="a+",encoding="utf-8")
new_file.writelines(fruits)
for line in new_file:
    print(line)

Метод seek()

Обратите внимание, что при чтении из файла ничего не печатается, потому что курсор файла находится в конце файла. Чтобы установить курсор в начало, вы можете использовать метод seek() файлового объекта:

cars=["Audi\n","Bentley\n","Toyota\n"]
new_file=open("newfile.txt",mode="a+",encoding="utf-8")
for car in cars:
    new_file.write(car)
print("Tell the byte at which the file cursor is:",new_file.tell())
new_file.seek(0)
for line in new_file:
    print(line)
Tell the byte at which the file cursor is: 115
Writing to a new file

Writing to a new file

Writing to a new file

Orange

Banana

Apple

Audi

Bentley

Toyota

Метод tell() файлового объекта сообщает, в каком байте находится курсор файла. В seek(offset,reference_point) опорными точками являются 0 (начало файла, используется по умолчанию), 1 (текущая позиция файла) и 2 (конец файла).

Операции поиска с конца, такие как seek(-2,2), недопустимы, если режим файла не включает 'b', что указывает на двоичный формат. Если файловый объект рассматривается как текстовый файл, разрешены только прямые операции, такие как seek(0,2).

Давайте попробуем передать другую опорную точку и смещение и посмотрим результат:

new_file.seek(4,0)
print(new_file.readline())
new_file.close()

# Результат:
# ing to a new file

Метод next()

Остался только метод next(), поэтому давайте завершим этот раздел руководства! Используем тот же файл с именем test1.txt.

file=open("test1.txt","r")
for index in range(5):
    line=next(file)
    print(line)
file.close()
1st line

2nd line

3rd line

4th line

5th line

Примечание: метод write() записывает данные не в файл, а в буфер. Вызов метода close() очищает буфер и записывает содержимое в файл. Если вы не хотите закрывать файл, используйте метод fileObject.flush() для очистки буфера и записи в файл.

Импорт романа “Моби Дик”

“Моби Дик” – это роман американского писателя Германа Мелвилла 1851 года. Мы будем работать с файлом moby_dick.txt. Это текстовый файл, содержащий начальные фразы “Моби Дика”, одного из величайших американских романов! На нем вы потренируетесь открывать текстовый файл, печатать его содержимое и, наконец, закрывать файл.

Вы можете скачать текстовый файл moby_dick.txt отсюда.

Выполним следующие действия:

  • Откроем файл moby_dick.txt в режиме “только чтение” и сохраним его в файле переменных
  • Распечатаем содержимое файла
  • Проверим, закрыт ли файл
  • Закроем файл с помощью метода close()
  • Снова проверим, закрыт ли файл
# Open a file: file
file = open('moby_dick.txt', 'r')

# Print it
print(file.read())
print('\n')
# Check whether file is closed
print('Is the file closed?:', file.closed)

# Close file
file.close()
print('\n')
# Check whether file is closed
print('Is the file closed?:', file.closed)
CHAPTER 1. Loomings.

Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of
the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get
such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly
take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.


Is the file closed?: False


Is the file closed?: True

Чтение романа “Моби Дик” с помощью контекстного менеджера

Вы можете связать объект файла с помощью конструкции контекстного менеджера, и вам не придется беспокоиться о закрытии файла. Файл не может быть доступен вне контекстного менеджера и закрывается после выполнения кода или ошибке.

Давайте выведем первые три строки текстового файла moby_dick.txt с помощью метода readline(). Обратите внимание, что по умолчанию файл открыт в режиме чтения.

with open('moby_dick.txt') as file:
    print(file.readline())
    print(file.readline())
    print(file.readline())
CHAPTER 1. Loomings.



Call me Ishmael. Some years ago--never mind how long precisely--having

Запись в файл JSON

Вы также можете записывать данные в файлы .json.

Javascript Object Notation (JSON) стал популярным методом обмена структурированной информацией по сети и между платформами. По сути, это текст с определенной структурой, и сохранение его в формате .json указывает, как читать эту структуру. Если не указать формать .json, большинство инструментов для чтения примут его как обычный текстовый файл.

Данные в json-файлах хранятся в виде пар “ключ: значение”. Такой формат позволяет удобно хранить как простые данные, так и довольно-таки сложные конструкции.

Взгляните на следующий простой JSON для стран и их столиц:

{
"Algeria":"Algiers",
"Andorra":"Andorra la Vella",
"Nepal":"Kathmandu",
"Netherlands":"Amsterdam",
}

Поскольку JSON состоит из массива пар ключ-значение, как показано в ячейке кода ниже, все, что до :, называется ключом, а после : – значением. Это очень похоже на словари Python, не так ли? Вы можете видеть, что данные разделены символами , и что фигурные скобки определяют объекты. Квадратные скобки используются для определения массивов в более сложных файлах JSON, как показано в следующем отрывке:

{
  "colors": [
    {
      "color": "black",
      "category": "hue",
      "type": "primary",
      "code": {
        "rgba": [255,255,255,1],
        "hex": "#000"
      }
    },
    {
      "color": "white",
      "category": "value",
      "code": {
        "rgba": [0,0,0,1],
        "hex": "#FFF"
      }
    },
    {
      "color": "red",
      "category": "hue",
      "type": "primary",
      "code": {
        "rgba": [255,0,0,1],
        "hex": "#FF0"
      }
    },
    {
      "color": "blue",
      "category": "hue",
      "type": "primary",
      "code": {
        "rgba": [0,0,255,1],
        "hex": "#00F"
      }
    },
    {
      "color": "yellow",
      "category": "hue",
      "type": "primary",
      "code": {
        "rgba": [255,255,0,1],
        "hex": "#FF0"
      }
    },
    {
      "color": "green",
      "category": "hue",
      "type": "secondary",
      "code": {
        "rgba": [0,255,0,1],
        "hex": "#0F0"
      }
    },
  ]
}

Обратите внимание, что файлы JSON также могут содержать различные типы данных в одном объекте!

Когда вы читаете файл с помощью функции read(), вы читаете строки из файла. Это означает, что когда вы читаете числа, вам нужно преобразовать их в целые числа с помощью функций преобразования типов данных, таких как int(). Для более сложных случаев использования вы всегда можете воспользоваться модулем JSON.

Если у вас есть объект x, вы можете просмотреть его строковое представление JSON с помощью простой строки кода:

# Importing json module
import json
my_data=["Reading and writing files in python",78546]
json.dumps(my_data)
'["Reading and writing files in python", 78546]'

Чтобы записать JSON в файл, вы можете использовать метод .dump():

with open("jsonfile.json","w") as f:
    json.dump(my_data,f)
f.close()

Давайте теперь откроем файл JSON, который вы создали с помощью метода dump. Если файл JSON открыт для чтения, вы можете декодировать его с помощью load(file) следующим образом:

with open("jsonfile.json","r") as f:
    jsondata=json.load(f)
    print(jsondata)
f.close()
['Reading and writing files in python', 78546]

Аналогично, более сложные словари можно хранить с помощью модуля JSON. Более подробную информацию вы можете найти здесь.

Теперь давайте разберем некоторые другие параметры метода open(). Начнем с буферизации.

Параметр buffering функции open()

Буфер хранит фрагмент данных из файлового потока операционной системы до тех пор, пока он не будет использован, после чего поступают дополнительные данные. Это похоже на буферизацию видео.

Буферизация полезна, когда вы не знаете размер файла, с которым работаете. Если размер файла превышает объем памяти компьютера, то вам может не хватить вычислительных мощностей вашего компьютера, либо он сильно загрузится. Размер буфера определяет, сколько данных может храниться одновременно, пока они не будут использованы. io.DEFAULT_BUFFER_SIZE может определить размер буфера по умолчанию для вашей платформы.

Опционально, вы можете передать целое число в buffering, чтобы установить параметры буферизации:

  • 0 для отключения буферизации (разрешено только в двоичном режиме)
  • 1 для выбора буферизации строк (допустимо только в текстовом режиме).
  • Любое целое число, большее 1, для указания размера в байтах чанка фиксированного размера.
  • Используйте отрицательные значения для установки политики буферизации на системное значение по умолчанию.

Если вы не указали никакой политики, она будет использоваться по умолчанию:

  • Двоичные файлы буферизуются кусками фиксированного размера.
  • Размер буфера выбирается в зависимости от “размера блока” базового устройства. На многих системах буфер обычно имеет длину 4096 или 8192 байта.
  • “Интерактивные” текстовые файлы (файлы, для которых isatty() возвращает True) используют буферизацию строк. Для остальных текстовых файлов используется политика, описанная выше для двоичных файлов. Обратите внимание, что isatty() можно использовать для проверки подключения к Tele-TYpewriter(-подобному) устройству.
import io
print("Default buffer size:",io.DEFAULT_BUFFER_SIZE)
file=open("test1.txt",mode="r",buffering=5)
print(file.line_buffering)
file_contents=file.buffer
for line in file_contents:
    print(line)
Default buffer size: 8192
False
b'1st line\r\n'
b'2nd line\r\n'
b'3rd line\r\n'
b'4th line\r\n'
b'5th line'

Обратите внимание, что если вы используете все аргументы в порядке, указанном в open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None), вам не нужно писать имя аргумента! Если вы пропускаете аргументы, потому что хотите сохранить значения по умолчанию, лучше написать все полностью.

Параметр errors функции open()

Необязательная строка, определяющая, как будут обрабатываться ошибки кодирования и декодирования. Этот аргумент нельзя использовать в двоичном режиме. Доступны различные стандартные обработчики ошибок.

file=open("test1.txt",mode="r",errors="strict")
print(file.read())
file.close()
1st line
2nd line
3rd line
4th line
5th line

errors="strict" вызывает ValueErrorException, если есть ошибка кодирования.

Параметр newline функции open()

newline управляет тем, как работает универсальный режим новых строк (он применяется только в текстовом режиме). Это может быть None, '', '\n', '\r' и '\r\n'. В примере выше вы видите, что передача None в newline переводит '\r\n' в '\n'.

  • Режим None – строки во входных данных могут заканчиваться на '\n', '\r' или '\r\n', и они переводятся в стандартный разделитель строк
  • " " – режим универсальных новых строк включен, но окончания строк возвращаются не переведенными
  • '\n','\r','\r\n' – входные строки завершаются только данной строкой, и окончание строки не переводится.

Обратите внимание, что универсальные новые строки – это способ интерпретации текстовых потоков, в котором все следующие символы распознаются как конец строки: соглашение Unix о конце строки '\n', соглашение Windows '\r\n' и старое соглашение Macintosh '\r'.

Также обратите внимание, что os.linesep возвращает системный разделитель строк по умолчанию:

file=open("test1.txt",mode="r",newline="")
file.read()
'1st line\r\n2nd line\r\n3rd line\r\n4th line\r\n5th line'
file=open("test1.txt",mode="r",newline=None)
file.read()
'1st line\n2nd line\n3rd line\n4th line\n5th line'
file.close()

Параметр encoding функции open()

Кодирование представляет собой преобразование символов в байтовые значения, то есть систему кодирования, в которой для представления символа используются байты. Это понятие часто всплывает при разговоре о хранении данных, передаче данных и вычислениях.

В Microsoft Windows кодировка по умолчанию зависит от операционной системы, в Linux это cp1252, но UTF-8. Поэтому при работе с текстовыми файлами хорошей практикой является указание кодировки символов. Обратите внимание, что двоичный режим не принимает аргумент кодировки.

Ранее вы прочитали, что можно использовать параметр errors для обработки ошибок кодирования и декодирования и что для работы с окончаниями строк используется newline. Теперь попробуйте воспроизвести следующий код:

with open("test1.txt",mode="r") as file:
    print("Default encoding:",file.encoding)
    file.close()
##change encoding to utf-8
with open("test1.txt",mode="r",encoding="utf-8") as file:
    print("New encoding:",file.encoding)
    file.close()
Default encoding: cp1252
New encoding: utf-8

Параметр closefd функции open()

Если значение closefd равно False и был указан дескриптор, а не имя файла, то при закрытии файла основной его дескриптор будет оставаться открытым. Если указано имя файла, closefd должен быть установлен в True, что является значением по умолчанию. В противном случае вы, вероятно, получите ошибку. Этот аргумент используется, чтобы обернуть существующий файловый дескриптор в реальный файловый объект.

Обратите внимание, что файловый дескриптор – это просто целое число, присвоенное файловому объекту операционной системой, чтобы Python мог запрашивать операции ввода-вывода. Метод .fileno() возвращает это целое число.

Если у вас уже есть целочисленный файловый дескриптор, открытый для канала ввода-вывода, вы можете обернуть вокруг него файловый объект, как показано ниже:

file=open("test1.txt","r+")
fd=file.fileno()
print("File descriptor assigned:",fd)

# Turn the file descriptor into a file object
filedes_object=open(fd,"w")
filedes_object.write("Data sciences\r\nPython")
filedes_object.close()
File descriptor assigned: 6

Чтобы не закрывать базовый файловый объект, вы можете использовать closefd=False:

file=open("test1.txt","r+")
fd=file.fileno()
print("File descriptor assigned:",fd)

# Turn the file descriptor into a file object
filedes_object=open(fd,"w",closefd=False)
filedes_object.write("Hello")
filedes_object.close()
file.close()
File descriptor assigned: 6

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

Двоичные файлы в Python

Двоичные файлы хранят данные в виде 0 и 1, которые могут быть прочитаны машиной. Байт – это набор из 8 битов. Один символ занимает в памяти один байт, состоящий из 8 битов. Например, двоичное представление символа ‘H’ – 01001000, а перевод этой 8-битной двоичной строки в десятичную дает 72.

binary_file=open("binary_file.bin",mode="wb+")
text="Hello 123"
encoded=text.encode("utf-8")
binary_file.write(encoded)
binary_file.seek(0)
binary_data=binary_file.read()
print("binary:",binary_data)
text=binary_data.decode("utf-8")
print("Decoded data:",text)
binary: b'Hello 123'
Decoded data: Hello 123

Когда вы открываете файл для чтения в двоичном режиме 'b', он возвращает байты данных.

Если вам когда-нибудь понадобится прочитать или записать текст из файла в двоичном режиме, убедитесь, что вы не забыли декодировать или закодировать его, как описано выше. Вы можете получить доступ к каждому байту через итерацию, как показано ниже, и это вернет целочисленные значения байтов (десятичное 8-битное двоичное представление каждого символа) вместо строк байтов:

for byte in binary_data:
    print(byte)
72
101
108
108
111
32
49
50
51

Атрибуты объектов файлов Python

Атрибуты файла предоставляют информацию о файле и состоянии файла.

АтрибутФункция
nameВозвращает имя файла
closedВозвращает значение True, если файл закрыт, и False в противном случае
modeРежим, в котором открыт файл
softspaceВозвращает булево значение, указывающее, нужно ли печатать пробел перед другим значением при использовании оператора print
encodingКодировка файла
# This is just another way you can open  a file
with open("test1.txt") as file:
    print("Name of the file:",file.name)
    print("Mode of the file:",file.mode)
    print("Mode of the file:",file.encoding)
    file.close()
print("Closed?",file.closed)
Name of the file: test1.txt
Mode of the file: r
Mode of the file: cp1252
Closed? True

Другие методы работы с файловым объектом

МетодФункция
readable()Возвращает значение True/False, указывающее, является ли файл читаемым
writable()Возвращает значение True/False, указывающее, является ли файл записываемым
fileno()Возвращает целочисленный дескриптор, используемый Python для запроса операций ввода/вывода от операционной системы
flush()Очищает внутренний буфер для файла
isatty()Возвращает значение True, если файл подключен к терминалу (TTY) или к чему-то подобному
truncate([size])Усекает файл до указанного количества байтов
next(iterator, [default])Позволяет итерироваться по файлу при использовании файла в качестве итератора. Прекращает итерацию при достижении конца файла (EOF) при чтении

Давайте попробуем все эти методы:

with open("mynewtextfile.txt","w+") as f:
    f.write("We are learning python\nWe are learning python\nWe are learning python")
    f.seek(0)
    print(f.read())
    print("Is readable:",f.readable())
    print("Is writeable:",f.writable())
    print("File no:",f.fileno())
    print("Is connected to tty-like device:",f.isatty())
    f.truncate(5)
    f.flush()
    f.seek(0)
    print(f.read())
f.close()
We are learning python
We are learning python
We are learning python
Is readable: True
Is writeable: True
File no: 8
Is connected to tty-like device: False
We ar

Работа с файлами с помощью модуля os

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

Давайте рассмотрим некоторые полезные методы модуля os, которые помогут вам работать с файлами и папками в вашей программе.

МетодФункция
os.makedirs()Создает новую папку
os.listdir()Возвращает список содержимого папки
os.getcwd()Возвращает текущую рабочую директорию
os.path.getsize()Возвращает размер (в байтах) файла, переданного в параметре
os.path.isfile()Проверяет, является ли переданный параметр файлом
os.path.isdir()Проверяет, является ли переданный параметр папкой
os.chdir()Изменяет текущую рабочую директорию на указанную папку
os.rename(current, new)Переименовывает файл с текущим именем на новое имя
os.remove(file name)Удаляет файл с указанным именем

Рассмотрим некоторые примеры этих методов:

import os
os.getcwd()
'C:\\Users\\hda3kor\\Documents\\Reading_and_Writing_Files'
os.makedirs("my_folder")
---------------------------------------------------------------------------

FileExistsError                           Traceback (most recent call last)

<ipython-input-12-f469e8a88f1b> in <module>
----> 1 os.makedirs("my_folder")


C:\Program Files\Anaconda3\lib\os.py in makedirs(name, mode, exist_ok)
    219             return
    220     try:
--> 221         mkdir(name, mode)
    222     except OSError:
    223         # Cannot rely on checking for EEXIST, since the operating system


FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'my_folder'

Следующий фрагмент кода создаст папку с именем my_folder:

open("my_folder\\newfile.txt","w")
print("Contents of folder my_folder\n",os.listdir("my_folder"))
print("---------------------------------")
print("Size of folder my_folder (in bytes)",os.path.getsize("my_folder"))
print("Is file?",os.path.isfile("test1.txt"))
print("Is folder?",os.path.isdir("my_folder"))
os.chdir("my_folder")
os.rename("newfile.txt","hello.txt")
print("New Contents of folder my_folder\n",os.listdir("my_folder"))
Contents of folder my_folder
 ['hello.txt', 'newfile.txt']
---------------------------------
Size of folder my_folder (in bytes) 0
Is file? True
Is folder? True



---------------------------------------------------------------------------

FileExistsError                           Traceback (most recent call last)

<ipython-input-13-6d2da66512fd> in <module>
      6 print("Is folder?",os.path.isdir("my_folder"))
      7 os.chdir("my_folder")
----> 8 os.rename("newfile.txt","hello.txt")
      9 print("New Contents of folder my_folder\n",os.listdir("my_folder"))


FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'newfile.txt' -> 'hello.txt'

Если вы зададите имя файла, который уже существует, Python выдаст ошибку FileExistsError. Для удаления файла можно использовать os.remove(filename):

os.getcwd()
os.remove("hello.txt")

Импорт плоских файлов с помощью NumPy

Числовые массивы Python, или более известные как массивы NumPy, – это стандарт Python для хранения числовых данных. Они эффективны, быстры и чисты. Они широко используются в линейной алгебре, статистике, машинном обучении и глубоком обучении. Массивы NumPy служат основой для чтения наборов данных изображений.

Они также полезны для таких пакетов, как Pandas и Scikit-learn. NumPy состоит из множества встроенных функций, которые можно использовать для анализа и манипулирования данными: эффективно и просто.

Данные MNIST

Образец набора данных MNIST в формате .csv можно загрузить отсюда. Более подробную информацию о наборе данных MNIST можно найти здесь, на веб-странице Янна Лекуна.

Сначала вы импортируете модуль NumPy, а затем используете метод loadtxt для импорта данных MNIST, как показано ниже:

import numpy as np
data = np.loadtxt('mnist.csv', delimiter=',')
print(data)
[[1. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [1. 0. 0. ... 0. 0. 0.]
 ...
 [2. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [5. 0. 0. ... 0. 0. 0.]]

Если ваш набор данных имеет заголовок со строковыми значениями, вы можете использовать параметр skiprows и пропустить первую строку. Аналогично, вы можете использовать параметр usecols для чтения только некоторых определенных столбцов.

Вы также можете передать dtype, т.е. тип данных, в который вы хотите импортировать ваши данные: integer, float, string и т.д.

Обратите внимание, что массивы NumPy способны работать только с одним типом данных, то есть в одном массиве не может быть смешанных типов данных.

Давайте проверим, сколько строк и столбцов имеет этот набор данных:

data.shape
(100, 785)

Заключение

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

В этой статье мы рассмотрели различные способы открытия, чтения, записи и закрытия файлов в Python, а также основные операции, которые можно выполнять над файлами, включая чтение и запись текстовых, бинарных и JSON-файлов.

Мы также изучили концепцию контекстного управления файлами, которая позволяет автоматически закрывать файлы после работы с ними, что упрощает код и предотвращает утечку ресурсов.

Надеюсь, что данная статья помогла вам разобраться с основами работы с файлами в Python и дала вам полезные инструменты для решения задач, связанных с обработкой файлов. Не забывайте, что работа с файлами – это лишь одна из множества возможностей, которые предоставляет Python, и с ее помощью вы можете создавать мощные и эффективные программы.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *