{ "cells": [ { "cell_type": "markdown", "id": "be7bc6cb", "metadata": {}, "source": [ "# Файлы #" ] }, { "cell_type": "markdown", "id": "cc8b2eae", "metadata": {}, "source": [ "На этой лекции мы поговорим с вами о файлах и том, как с ними работать.\n", "\n", "С файлами, на самом деле, в Python'е никаких проблем не должно возникнуть.\n", "Все довольно просто. Чтобы открыть файлы мы используем встроенный метод `open`, встроенную функцию `open`, и передаем ей `filename`." ] }, { "cell_type": "code", "execution_count": 3, "id": "5974cb39", "metadata": {}, "outputs": [], "source": [ "f = open(\"filename\")" ] }, { "cell_type": "markdown", "id": "aee8d1e2", "metadata": {}, "source": [ "У нас возвращается файловый объект, с которым мы потом можем работать, для того чтобы записывать данные или читать данные из файлов. \n", "\n", "Можно их открывать на запись, на чтение, на чтение и запись, и на дозапись. Делается это с помощью модов, которым мы тоже придаем функцию `open`. Например, `a` — это дозапись, `w` — это, очевидно, запись, `r` — это прочтение, `r+` — это запись и чтение одновременно. Точно так же мы можем открывать файл в бинарном виде, то есть работать с бинарными данными, и происходит все аналогично обычному типу. Мы просто добавляем в мод букву `b`." ] }, { "cell_type": "code", "execution_count": 2, "id": "3584b6c2", "metadata": {}, "outputs": [], "source": [ "text_modes = [\"r\", \"w\", \"a\", \"r+\"]\n", "binary_modes = [\"br\", \"bw\", \"ba\", \"br+\"]" ] }, { "cell_type": "markdown", "id": "83c0ce60", "metadata": {}, "source": [ "Чтобы открыть файл, например, на запись, мы передаем мод `w` в функцию `open`. Чтобы записать данный файл, мы берем наш файловый объект и пользуемся методом файла `write`, передавая туда строку. В данном случае мы передаем строку, и наш метод `write` возвращает количество символов, которые мы записали. Если это будет байтовая информация, то, собственно, это будет не количество символов, а количество байт. Чтобы закрыть файл, нам нужно вызвать метод `close`, и файл нужно обязательно закрывать." ] }, { "cell_type": "code", "execution_count": 4, "id": "2b25c2b5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "47" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = open(\"filename\", \"w\")\n", "\n", "f.write(\"The world is changed.\\nI taste it in the water.\\n\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "ebc3244a", "metadata": {}, "outputs": [], "source": [ "f.close()" ] }, { "cell_type": "markdown", "id": "16383eec", "metadata": {}, "source": [ "Если вы откроете файл и не закроете файл, может произойти что-нибудь страшное и ужасное. На самом деле нет, но принято файлы закрывать, и мы поговорим с вами о том, как с этим работать. Итак, чтобы открыть файл на чтение и запись, нам нужно использовать `r+`, и мы можем читать данные из файла с помощью метода `read`. `Read` по умолчанию читает столько, сколько сможет. Если файл не поместится в памяти, то это ваши проблемы. Вы также можете указать в методе `read` конкретное количество информации, которое вы хотите прочитать, передав `size`, но по умолчанию читается весь файл и выводится, собственно." ] }, { "cell_type": "code", "execution_count": 6, "id": "9d740b8c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'The world is changed.\\nI taste it in the water.\\n'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = open(\"filename\", \"r+\")\n", "f.read()" ] }, { "cell_type": "code", "execution_count": 7, "id": "aee2da15", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "49" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f.tell()" ] }, { "cell_type": "markdown", "id": "1d4c7a2b", "metadata": {}, "source": [ "Здесь мы выводим все строчки, которые туда записали, и видим, что на самом деле информация в файл попала. Очень важный момент. Когда мы прочитали весь файл, у нас указатель того, где мы сейчас находимся в файле — в самом конце. В данном случае это 47 символов. Если мы попробуем прочитать еще раз, то мы ничего не найдем, потому что мы весь файл уже прочитали и у нас пойнтер в самом конце." ] }, { "cell_type": "code", "execution_count": 8, "id": "cf719f78", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f.read()" ] }, { "cell_type": "markdown", "id": "9b0798a6", "metadata": {}, "source": [ "Для того чтобы прочитать его, например, заново, нам нужно использовать метод `seek` и перенести указатель на начало файла. Как вы видите, он равен нулю, и теперь мы можем действительно читать данные заново и, например, опять же закрыть файл, потому что файлы всегда нужно закрывать." ] }, { "cell_type": "code", "execution_count": 9, "id": "57b6f5bb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f.seek(0)\n", "f.tell()" ] }, { "cell_type": "code", "execution_count": 10, "id": "4ce93652", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The world is changed.\n", "I taste it in the water.\n", "\n" ] } ], "source": [ "print(f.read())\n", "f.close()" ] }, { "cell_type": "markdown", "id": "8109309b", "metadata": {}, "source": [ "Собственно, кроме обычного метода `read`, есть также полезные методы для работы со строками, которые позволяют вам читать строки, одну, например, или несколько.\n", "\n", "Чтобы прочитать конкретно одну строку, можно использовать метод `readline` у того же файлового объекта, и метод вернет строку, разбив по символу переноса строки. Как видите, у нас вернулась только первая строка без второй." ] }, { "cell_type": "code", "execution_count": 12, "id": "1a2fd52d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The world is changed.\n", "\n" ] } ], "source": [ "f = open(\"filename\", \"r+\")\n", "print(f.readline())\n", "f.close()" ] }, { "cell_type": "markdown", "id": "16da382f", "metadata": {}, "source": [ "Если вам интересно прочитать сразу все строки, разбить их по символу переноса строки и записать все это, например, в список, можно использовать метод `readlines`. Он сделает именно это — вернет список строк, разбитых по символу перевода строки." ] }, { "cell_type": "code", "execution_count": 13, "id": "1d65e32e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['The world is changed.\\n', 'I taste it in the water.\\n']" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = open(\"filename\", \"r+\")\n", "f.readlines()" ] }, { "cell_type": "markdown", "id": "9fb151d1", "metadata": {}, "source": [ "Если мы закроем файл и попробуем его прочитать, очевидно, у нас ничего не получится, потому что закрытый файл прочитать нельзя. Будьте внимательны." ] }, { "cell_type": "code", "execution_count": 14, "id": "13c0a8d3", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "I/O operation on closed file.", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mread\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mValueError\u001b[0m: I/O operation on closed file." ] } ], "source": [ "f.close()\n", "f.read()" ] }, { "cell_type": "markdown", "id": "6ac70071", "metadata": {}, "source": [ "На самом деле, я рекомендую вам работать с файлами немного другим образом. Существует специальная вещь, называемая контекстный менеджер, который вам позволяет не заботиться о закрытии файлов. Вы можете открыть файл с помощью оператора `with`, и записать в файловый объект переменную `f` и потом работать с ним внутри этого контекстного блока и не закрывать его, потому что контекстный менеджер заботится об этом за вас." ] }, { "cell_type": "code", "execution_count": 15, "id": "ed64d12d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The world is changed.\n", "I taste it in the water.\n", "\n" ] } ], "source": [ "with open(\"filename\") as f:\n", " print(f.read())" ] }, { "cell_type": "markdown", "id": "7318dd16", "metadata": {}, "source": [ "Про контекстный менеджер мы поговорим позднее, а пока просто можете использовать эту конструкцию и не заботиться о том, чтобы закрывать файл.\n", "\n", "Итак, с файлами в Python работать довольно просто. У нас есть файловые объекты, мы можем в них писать, из них читать. Не забывайте закрывать файлы или используйте контекстный менеджер." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 5 }