Обучающий курс: https://stepik.org/course/100707
Начинаем работу с файлами. Функция open() для открытия файла. Методы read(), readline() и readlines() для чтения данных из файла. Цикл for для чтения данных. Методы seek() и tell() для работы с файловой позицией. Метод close() для закрытия файла.
Telegram-канал: https://t.me/python_selfedu
Оглавление (3 сегментов)
Segment 1 (00:00 - 05:00)
Здравствуйте, дорогие друзья. Я Сергей Балакерев, и мы продолжаем базовый курс по языку Python. На этом занятии мы с вами научимся читать данные из файлов. Я думаю, вы все прекрасно понимаете, что такое файлы и что они хранятся, как правило, на внешних носителях. Часто это жёсткий диск устройства или флеш-память или SSD-диск, бывают и другие носители. Главная особенность файлов - сохранение информации после отключения устройства от питания. Разумеется, язык Python умеет работать с файлами. И начнём со знакомства вот такой вот функции, которая называется Open. Эта функция открывает указанный файл на чтение или запись данных по умолчанию на чтение. И у неё вот такие вот основные параметры. Первый параметр - файл. Здесь прописывается путь к файлу, который мы собираемся открывать. Дальше режим доступа к файлу, либо на чтение, либо на запись. Есть некоторые другие режимы доступа. Мы об этом будем подробно говорить. Ну и, наконец, кодировка. Кодировка самого файла. Сейчас мы с вами увидим, как можно использовать все эти параметры. Но начнём вот с этого самого первого параметра файл. Давайте представим, что у нас имеется такая вот иерархия каталогов и файлов. И мы с вами находимся вот в этом каталоге, то есть в каталоге. И в нём находится файл X1. Это рабочий каталог. То есть место, где исполняется наш файл, по умолчанию является рабочим каталогом. Тогда, чтобы обратиться вот к этому файлу, myфай txt, путь можно прописать следующим образом. Либо как относительный просто myфайл, потому что этот файл находится здесь же в рабочем каталоге, либо абсолютном. То есть мы прописываем вначале вот этот вот диск D, то есть как пример Dдиск, потом мы указываем каталог app. Ну и, наконец, вот это вот файл myфа text. Либо, как вариант, мы можем вот эти вот разделители файлов прописывать с помощью символа слш. Это более предпочтительный вариант, потому что вот такой-то разделитель, обратный слш, он используется, как правило, в операционной системе Windows. А вот такой обычный слш, он работает как под Windows, так и под операционной системы Linux. Поэтому такой-то вариант, он является более предпочтительным. Отлично, с этим разобрались. Давайте теперь посмотрим, как можно обратиться вот к этому файлу Image TXT, который находится в подкаталоге images. То есть вот это вот подкаталог, он находится в рабочем каталоге относительно вот этого вот файла X1. Именно поэтому относительный путь можно прописать следующим образом. Мы указываем вот это вот под каталог images. Ну и дальше вот это вот файл image txt. Если же мы хотим указать абсолютный путь, то он в данном случае будет выглядеть так: D, потом вот это вот каталог app, потом под каталог, ну и, наконец-то, этот вот файл txt. То есть мы можем прописывать путь и вот таким вот образом, и вот таким вот. Это, по сути дела, одно и то же. Теперь давайте посмотрим, как можно прописать путь вот к этому файлу. O outxt. В этом случае относительный путь будет выглядеть следующим образом. Две точки и слэш. Вот эти вот две точки слш - это выход вот из этого вот родительского каталога. То есть мы выходим из каталога App, где находимся в данный момент, на уровень выше, то есть на самом деле к диску D обращаемся и уже там берём вот этот файлT. Поэтому относительный путь у нас получается вот такой вот. Ну а абсолютно будет просто d и outxt. Ну и, наконец, путь вот к этому файлу DAT будет выглядеть следующим образом. В случае относительного пути, опять же, две точки, мы выходим из родительского каталога, потом указываем вот этот вот каталог parent, ну и, наконец, файл PRT DAT, либо абсолютный путь D, каталоal parent и файл PRT dat. То есть вот принцип, по которому прописываются пути к файлам. И в примере, который мы сейчас рассмотрим, мы будем обращаться вот к такому файлу MyФаxt, который будет находиться в текущем рабочем каталоге. Поэтому путь к нему мы можем прописать вот в таком вот виде. Итак, для того, чтобы открыть файл, следует воспользоваться такой вот функцией Open. И в самом простом случае мы просто прописываем название того файла, который хотим открыть. По умолчанию он открывается на чтение. Если сейчас запустить программу, то, соответственно, никаких ошибок нету. Файл открывается, потому что он присутствует вот здесь вот в текущем рабочем каталоге. Вот он у меня здесь расположен. Соответственно, открывается. И после того, как программа завершается, он автоматически закрывается. Если же мы здесь укажем неправильное имя файла, например, вот так вот myфа 2x, то возникнет ошибка. Ошибка, которая звучит так вот: file not found error. То есть не найден файл. Поэтому вот эти вот пути нужно прописывать аккуратно. И позже мы с вами увидим, как можно избежать такой ошибки, чтобы программа не прерывалась при неверно указанном файле. Итак, вот эта вот функция Open, она по умолчанию открывает файл на чтение. Это значит, что в этом режиме можем только считывать информацию из файла, но не записывать.
Segment 2 (05:00 - 10:00)
Как же спрашивается читать данные из файла? Для этого вот у этого объекта файл, то есть файл - это файловый объект, у него есть множество разных методов. И вот, в частности, вот это вот метод read позволяет читать информацию из файла. Если мы здесь ничего не прописываем, то будет читаться всё, что находится в этом файле. Мы прочитаем данные вот в эту переменную текст и выведем её на экран. Printте. Запустим программу и видим вот такие вот корокозябры. С чем это связано? Дело в том, что вот этот вот файл, myфайте у меня сохранён в кодировке уf, а функция read по умолчанию, по крайней мере у меня, читает данные в кодировке Windows 1251. То есть несовпадение кодировок приводит вот к таким вот краркозябрам. Давайте это поправим. Для этого вот здесь вот, когда мы открываем файл, дополнительно можем указать кодировку с помощью вот такого вот аргумента encodдиing. Соответственно, здесь прописываем УТ8, запускаем программу, и теперь всё нормально отображается. Но что, если нам нужно прочитать из файла не всю информацию, а только несколько символов? Для этого вот в этом методе read достаточно указать первым аргументом максимальное число читаемых символов, например, четыре. Запустим программу и видим первые четыре символа. Но смотрите, если мы с вами снова вызовем эту же самую функцию сразу с выводом информации на экран, поэтому напишу вот так вот print file read 4, то смотрите, что у нас получится. У нас читается сначала первые четыре символа, а потом следующие четыре символа. То есть вот это вот первый метод 34 читает первые 4 байта, а второй метод 34 следующие 4 байта и так далее. Почему это работает именно таким образом? Смотрите, когда мы первый раз вызываем вот этот метод readт со значениемчетыре, то читается первые четыре символа. Вот они. То есть дефис, пробел, s и к. Вот эта вот зелёная стрелочка называется файловой позицией. И файловая позиция указывает, с какого места следует продолжать чтение данных. То есть вот эта вот функция read и подобны ей функции, все остальные, они читают данные не с начала всегда файла, а с того места, на которое указывает вот эта вот файловая позиция. И по мере того, как считываются данные, файловая позиция автоматически перемещается. Поэтому, когда мы вызовем этот метод ещё раз, то будут прочитаны, соответственно, вот эти вот четыре символа и так далее. Вызовем ещё раз, ещё четыре символа, потом ещё четыре символа и так далее. И всё благодаря наличию вот этой вот файловой позиции. То есть все функции чтения данных из файла, они читают данный не с самого начала, а с того места, на которое указывает вот эта вот файловая позиция. Ну а когда мы доходим до конца файла, то здесь находится специальный символ, который называется eo of, то есть end ofфаile, означающий конец файла. Так вот, смотрите, при необходимости на практике мы можем управлять положением вот этой вот файловой позиции. И для этого существует специальный метод, который называется сик. Мы здесь указываем позицию, на которой хотел сместить вот эту вот файловую позицию. Ну а здесь флаг. Относительно чего будем сдвигать по умолчанию от начала файла. Давайте посмотрим, как она будет работать. Смотрите, если вот здесь вот мы с вами после того, как первый раз вызвали метод read 4, мы сдвинем файловую позицию снова в начало. И сделать это можно следующим образом. Значит, объект файл метод se и здесь укажем ноль. То есть мы сдвинем файловую позицию в самое начало. Ноль означает сдвинуть в самое начало. Запустим программу. И теперь оба метода читают одни и те же данные. То есть первые четыре символа. Если же нам требуется узнать положение текущей файловой позиции, то для этого используется такой вот метод, который называется. Давайте выведем его на экран и посмотрим, чему он будет в данном случае равен. Мы видим число восемь. То есть мы прочитали первые четыре символа и файловая позиция равна восьми. Почему восьми, а не четырём? Дело в том, что в кодировке у ТФ8 каждая буква русского алфавита занимает 2 байта. И так как мы прочитали первые четыре символа, каждый по два байта получает смещение 8 байт. То есть вот эта вот файловая позиция, она показывает смещение именно в байтах, не в символах, а в байтах. И вот это вот нужно хорошо запомнить. Отлично. В целом, мы с вами разобрались, как можно в самом простом варианте читать данные из файла и управлять файловой позиции. Давайте теперь посмотрим, как можно читать информацию из файла построчно. И предположим, мы хотим вот из этого открытого файла прочитать первую строку. Для этого можем вызвать вот этот вот метод, который называется readl. Вывезем на экран то, что у нас получится. printтекст, запускаем программу и видим, что как раз прочиталась только первая стручка. Если мы с вами ещё раз вызовем этот метод, давайте это сделаем следующим образом. print readline, чтобы
Segment 3 (10:00 - 13:00)
мы видели, что читается, запускаем программу и видим уже две строчки. Причём эти стручки выводятся через вот эти вот пустые струки. Почему так получилось? Дело в том, что вот этот вот метод readline, он читает информацию из файла, пока не встретится вот такой вот специальный символ с/N. Сn означает перевод на новую строку. То есть это, по сути дела, маркер окончания строки. И вот этот вот символ сN, он тоже читается этим методом. Поэтому в строке текст находятся не только вот эти вот символы, но и ещё вот этот вот символ перевода строки. Поэтому мы видим вот эту вот первую строку вместе с переводом строки. Потом функция print добавляет ещё свой перевод строки и получается такая вот пустая строка. Поэтому, если вот здесь вот в print мы пропишем вот так вот end и просто кавычки, то у нас как раз останется только один перевод строки вот это вот сшn. То есть вот этот вот метод rline, он читает информацию либо пока не встретится вот этот символ с/n, либо пока не будет достигнут конец файла. Если же мы хотим построчно прочитать весь вот этот вот файл, то сделать это можно следующим образом. С помощью цикла Фо мы воспользуемся вот этим вот файловым объектом. Файловый объект - это итериемый объект, поэтому с помощью цикла фом его вот так вот перебрать. Ну и, соответственно, на каждой итерации будет читаться очередная строка вот из этого вот файла. Давайте в этом убедимся. Запускаем программу и видим все вот эти вот строчки. Опять же, все они выводятся через строчку, то есть содержит этот вот символ перевода строки. Конечно, дополнительно мы здесь можем вызвать вот этот вот методстрип, который удаляет как раз вот этот символ с/n. Запускаем программу. И теперь никаких лишних пустых строк у нас нет. Или же мы можем прочитать все строчки с помощью метода, который называется readlines. Давайте сохраним это в какой-либо переменной S, например, и выведем её на экран. Запускаем программу и получаем следующее. Вот у нас первая строка. И вот здесь вот как раз хорошо видно, что все строки содержат вот этот символ сN, то есть сN - это перевод на новую строку. Здесь у нас то же самое, ну и так далее. Однако вот этот вот метод readl следует использовать с осторожностью, потому что может возникнуть с ошибка нехватки памяти. Но, например, читаем книжку "Войно и мир". Представьте, какой там объём. И всё это будет сразу сохраняться вот в этот список S. В итоге будет получаться большой расход памяти и, скорее всего, неоправданный. Поэтому использовать этот метод можно только в том случае, если мы уверены, что читаемый файл небольшой. То есть вот так вот в целом выглядят методы чтения данных из файла. Ну и в конце, после того, как мы с вами поработали с файлом, его следует закрыть, чтобы освободить все ресурсы, которые связан с этим файлом. Ну и кроме того, у нас не будет проблем в потере данных при записи данных файл. Поэтому нужно запомнить такое правило. После того, как мы поработали с файлом, его обязательно нужно закрыть. На этом мы с вами завершим первый заколами. Из этого занятия вы должны запомнить, как открыть файл на чтение, как прочитать все данные или часть данных, как поменять файловую позицию. И в конце не забываем закрывать открытые файлы. เฮ