Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 74
Текст из файла (страница 74)
Как будет показано дальше, они могут применяться даже к программным компонентам, которые физически не являютсяпоследовательностями, – к любым объектам, поддерживающим возможностьвыполнения итераций, включая файлы, которые автоматически читаютсястрока за строкой.Кортежи имеют весьма ограниченный набор методов, по сравнению со списками и строками. В версиях �������������������������������������������������Python������������������������������������������� 2.6 и 3.0 они обладают всего двумя методами – index и count, которые действуют точно так же, как одноименные методысписков:>>>>>>1>>>3>>>3T = (1, 2, 3, 2, 4, 2)T.index(2)# Методы кортежей в Python 2.6 и 3.0# Первое вхождение находится в позиции 2T.index(2, 2)# Следующее вхождение за позицией 2T.count(2)# Определить количество двоек в кортежеДо выхода версий 2.6 и 3.0 кортежи вообще не имели методов – это было древнее соглашение в языке Python, касающееся неизменяемых типов, котороенесколько лет тому назад было из практических соображений нарушено длястрок, а совсем недавно – для чисел и кортежей.Кроме того, следует заметить, что правило неизменяемости применяетсятолько к самому кортежу, но не к объектам, которые он содержит.
Например,список внутри кортежа может изменяться как обычно:>>> T = (1, [2, 3], 4)>>> T[1] = ‘spam’# Ошибка: нельзя изменить сам кортежTypeError: object doesn’t support item assignment>>> T[1][0] = ‘spam’>>> T(1, [‘spam’, 3], 4)# Допустимо: вложенный изменяемый объект можно изменитьДля большинства программ такой одноуровневой неизменяемости для обычного использования кортежей вполне достаточно. О чем, совершенно случайно,и рассказывается в следующем разделе.Зачем нужны кортежи, если есть списки?Похоже, что это самый первый вопрос, который задают начинающие программисты, узнав о кортежах: «Зачем нам нужны кортежи, если у нас уже имеютсясписки?» Некоторые из причин корнями уходят в прошлое.
Создатель языкаPython – математик по образованию, и он рассматривал кортежи, как простыеассоциации объектов, а списки – как структуры данных, допускающие изменения в течение всего времени своего существования. На самом деле, такое ис-289Файлыпользование слова «кортеж» уходит корнями в математику, так же, как и егоиспользование для обозначения строк в таблицах реляционных баз данных.Однако более правильным будет считать, что неизменяемость кортежей обеспечивает своего рода поддержку целостности – вы можете быть уверены, чтокортеж не будет изменен посредством другой ссылки из другого места в программе, чего нельзя сказать о списках.
Тем самым кортежи играют роль объявлений «констант», присутствующих в других языках программирования,несмотря на то, что в языке Python это понятие связано с объектами, а не с переменными.Кроме того, существуют ситуации, в которых кортежи можно использовать,а списки – нет. Например, в качестве ключей словаря (пример с разреженнымиматрицами в главе 8). Некоторые встроенные операции также могут требоватьили предполагать использование кортежей, а не списков. Следует запомнить,что списки должны выбираться, когда требуются упорядоченные коллекции, которые может потребоваться изменить. Кортежи могут использоватьсяв остальных случаях, когда необходимы фиксированные ассоциации объектов.ФайлыВозможно, вы уже знакомы с понятием файла – так называются именованныеобласти постоянной памяти в вашем компьютере, которыми управляет операционная система.
Последний основной встроенный тип объектов, который мыисследуем в нашем обзоре, обеспечивает возможность доступа к этим файламиз программ на языке Python.Проще говоря, встроенная функция open создает объект файла, который обеспечивает связь с файлом, размещенным в компьютере. После вызова функцииopen можно выполнять операции чтения и записи во внешний файл, используяметоды полученного объекта.По сравнению с типами, с которыми вы уже знакомы, объекты файлов выглядят несколько необычно. Они не являются ни числами, ни последовательностями или отображениями – для задач работы с файлами они предоставляютодни только методы. Большинство методов файлов связаны с выполнениемопераций ввода-вывода во внешние файлы, ассоциированные с объектом, носуществуют также методы, которые позволяют переходить на другую позициюв файле, выталкивать на диск буферы вывода и так далее.
В табл. 9.2 приводятся наиболее часто используемые операции над файлами.Таблица 9.2. Часто используемые операции над файламиОперацияИнтерпретацияoutput = open(r’C:\spam’, ‘w’) Открывает файл для записи(‘w’ означает write – запись)input = open(‘data’, ‘r’)Открывает файл для чтения(‘r’ означает read – чтение)input = open(‘data’)То же самое, что и в предыдущей строке(режим ‘r’ используется по умолчанию)aString = input.read()Чтение файла целиком в единственную строку290Глава 9. Кортежи, файлы и все остальноеТаблица 9.2 (продолжение)ОперацияИнтерпретацияaString = input.read(N)Чтение следующих N символов (или байтов)в строкуaString = input.readline()Чтение следующей текстовой строки(включая символ конца строки) в строкуaList = input.readlines()Чтение файла целиком в список строк(включая символ конца строки)output.write(aString)Запись строки символов (или байтов) в файлoutput.writelines(aList)Запись всех строк из списка в файлoutput.close()Закрытие файла вручную (выполняется поокончании работы с файлом)output.flush()Выталкивает выходные буферы на диск,файл остается открытымanyFile.seek(N)Изменяет текущую позицию в файле для следующей операции, смещая ее на N байтов отначала файла.for line in open(‘data’):операции над lineИтерации по файлу, построчное чтениеopen(‘f.txt’,encoding=’latin-1’)Файлы с текстом Юникода в Python 3.0(строки типа str)open(‘f.bin’, ‘rb’)Файлы с двоичными данными в Python 3.0(строки типа bytes)Открытие файловЧтобы открыть файл, программа должна вызвать функцию open, передав ейимя внешнего файла и режим работы.
Обычно в качестве режима используется строка ‘r’, когда файл открывается для чтения (по умолчанию), ‘w’ – когдафайл открывается для записи или ‘a’ – когда файл открывается на запись в конец. В строке режима могут также указываться другие параметры:•• Добавление символа b в строку режима означает работу с двоичными данными (в версии 3.0 отключается интерпретация символов конца строкии кодирование символов Юникода).•• Добавление символа + означает, что файл открывается для чтения и для записи (то есть вы получаете возможность читать и записывать данные в одини тот же объект файла, часто совместно с операцией позиционированияв файле).Оба аргумента функции open должны быть строками.
Кроме того, функция может принимать третий необязательный аргумент, управляющий буферизацией выводимых данных, – значение ноль означает, что выходная информацияне будет буферизироваться (то есть она будет записываться во внешний файлсразу же, в момент вызова метода записи). Имя внешнего файла может вклю-Файлы291чать платформозависимые префиксы абсолютного или относительного путик файлу. Если путь к файлу не указан, предполагается, что он находится в текущем рабочем каталоге (то есть в каталоге, где был запущен сценарий).
Здесьмы рассмотрим лишь самые основы работы с файлами и исследуем несколькопростых примеров, но не будем исследовать все параметры, определяющие режимы работы с файлами. За дополнительной информацией обращайтесь к руководству по стандартной библиотеке языка Python.Использование файловКак только будет получен объект файла, вы можете вызывать его методы длявыполнения операций чтения или записи. В любом случае содержимое файлав программах на языке Python принимает форму строк – операция чтения возвращает текст в строках, и метод записи принимает информацию в виде строк.Существует несколько разновидностей методов чтения и записи, а в табл. 9.2перечислены лишь наиболее часто используемые из них. Ниже приводятся несколько самых основных замечаний по использованию файлов:Для чтения строк лучше использовать итераторы файловНесмотря на то что методы чтения и записи, перечисленные в таблице, являются наиболее часто используемыми, имейте в виду, что самый лучший,пожалуй, способ чтения строк из файла на сегодняшний день состоит в том,вообще не использовать операцию чтения из файла – как будет показанов главе 14, файлы имеют итератор, который автоматически читает информацию из файла строку за строкой в контексте цикла for, в генераторах списков и в других итерационных контекстах.Содержимое файлов находится в строках, а не в объектахОбратите внимание: в табл. 9.2 показано, что данные, получаемые из файла,всегда попадают в сценарий в виде строки, поэтому вам необходимо будетвыполнять преобразование данных в другие типы объектов языка Python,если эта форма представления вам не подходит.
Точно так же, при выполнении операции записи данных в файл, в отличие от инструкции print,интерпретатор Python не выполняет автоматическое преобразование объектов в строки – вам необходимо передавать методам уже сформированныестроки. Поэтому при работе с файлами вам пригодятся рассматривавшиесяранее инструменты преобразования данных из строкового представленияв числовое и наоборот (например, int, float, str, а также выражения форматирования строк и метод format). Кроме того, в состав Python входят дополнительные стандартные библиотечные инструменты, предназначенные дляработы с универсальным объектом хранилища данных (например, модульpickle) и обработки упакованных двоичных данных в файлах (например,модуль struct).
С действием обоих модулей мы познакомимся ниже, в этойже главе.Вызов метода close является необязательнымВызов метода close разрывает связь с внешним файлом. Как рассказывалось в главе 6, интерпретатор Python немедленно освобождает память, занятую объектом, как только в программе будет утеряна последняя ссылкана этот объект. Как только объект файла освобождается, интерпретаторавтоматически закрывает ассоциированный с ним файл (что происходиттакже в момент завершения программы). Благодаря этому вам не требу-292Глава 9.
Кортежи, файлы и все остальноеется закрывать файл вручную, особенно в небольших сценариях, которыевыполняются непродолжительное время. С другой стороны, вызов методаclose не повредит, и его рекомендуется использовать в крупных системах.Строго говоря, возможность автоматического закрытия файлов не является частью спецификации языка, и с течением времени такое поведение может измениться. Следовательно, привычку вызывать метод close вручнуюможно только приветствовать. (Альтернативный способ автоматическогозакрытия файлов приводится ниже, в этом же разделе, где обсуждаютсяменеджеры контекста объектов файлов, которые используются в новойинструкции with/as, появившейся в Python 2.6 и 3.0.)Файлы обеспечивают буферизацию ввода-вывода и позволяют производить позиционирование в файлеВ предыдущем абзаце отмечается важность явного закрытия файлов, потому что в этот момент освобождаются ресурсы операционной системыи выталкиваются выходные буферы. По умолчанию вывод в файлы всегдавыполняется с помощью промежуточных буферов, то есть в момент записитекста в файл он не попадает сразу же на диск – буферы выталкиваютсяна диск только в момент закрытия файла или при вызове метода flush.