Модель объекта файла в Python 3.X

model obekta fajla v python 3 x Инструменты для работы с файлами и каталогами

Как и в случае со строковыми типами, о которых говорилось в главе 2, поддержка файлов в Python 3.X стала гораздо богаче, чем в предыдущих версиях. Как уже отмечалось ранее, в Python 3.X строки типа str всегда представляют текст Юникода (символы ASCII или многобайтовые символы), а строки типов bytes и bytearray представляют простые двоичные данные. Python 3.X проводит подобные различия между файлами, содержащими текст и двоичные данные:

     Текстовые файлы содержат текст, состоящий из символов Юникода. Содержимое текстовых файлов в сценариях всегда представляется в виде строк типа str — последовательностей символов (точнее, последовательностей «кодовых пунктов» Юникода). Для текстовых файлов автоматически выполняется преобразование символов конца строки, о котором рассказывается в этой главе, а к содержимому файлов автоматически применяются операции кодирования/деко- дирования: данные кодируются в двоичное представление при записи в файл и декодируются обратно в Юникод при чтении из файла, в соответствии с указанной или используемой по умолчанию кодировкой. Кодирование является тривиальной операцией для текста ASCII, но может быть весьма сложной в других случаях.

     Двоичные файлы содержат обычные 8-битовые байты. Содержимое двоичных файлов в сценариях всегда представляется в виде строк байтов, обычно в виде объекта типа bytes — последовательности коротких целых чисел, которые поддерживают большинство операций, присущих типу str, и отображаются как последовательности символов ASCII, когда это возможно. Для двоичных файлов не предусматривается никаких преобразований данных при чтении или записи: ни преобразования символов конца строки, ни кодирования/ декодирования в Юникод.

На практике текстовые файлы используются для хранения действительно текстовых данных, а двоичные файлы — для хранения таких элементов, как упакованные двоичные данные, изображения, аудиоданные, выполняемый программный код и так далее. Программно эти два типа файлов различаются с помощью аргумента со строкой режима, который передается функции open: дополнительный символ «b» (например, rb’, ‘wb’) означает, что файл содержит двоичные данные. Для создания нового содержимого текстовых файлов используются обычные строки (например, spamили bytes.decode()), а для создания нового содержимого двоичных файлов — строки байтов (например, bspamили str.encode()).

Если в вашей практике область применения файлов не ограничивается использованием текста в кодировке ASCII, различия между представлением текстовых и двоичных данных в версии 3.X иногда будут сказываться на вашем программном коде. При работе с текстовыми файлами требуется использовать строки типа str, а с двоичными файлами — строки байтов. Поскольку вы не сможете смешивать эти типы в выражениях, вам придется внимательно подходить к вопросу выбора режима открытия файла. Многие встроенные инструменты, которые мы будем использовать в этой книге, делают этот выбор за нас — модули struct и pickle, например, в версии 3.X работают со строками байтов, а пакет xml — с Юникодом. Кроме того, о различиях между текстовыми и двоичными данными в версии 3.X необходимо помнить даже при использовании системных инструментов, таких как дескрипторы каналов и сокеты, потому что на сегодняшний день эти инструменты передают данные в виде строк байтов (впрочем, при необходимости эти данные можно кодировать и декодировать как текст Юникода).

Кроме того, при работе с текстовыми файлами выполняется обязательное декодирование их содержимого в Юникод в соответствии с выбранной кодировкой, поэтому вам придется использовать двоичный режим для чтения содержимого файлов, не поддающихся декодированию, в виде строк байтов (или обрабатывать исключения декодирования в Юникод с помощью инструкций try и пропускать такой файл целиком). Это относится и к собственно двоичным файлам, и к текстовым файлам, для представления текста в которых используется неподдерживаемая или неизвестная кодировка. Как мы увидим далее в этой главе, в версии 3.X строки типа str всегда содержат текст Юникода, поэтому иногда придется использовать строки байтов для представления имен файлов при использовании таких инструментов, как os.listdir, glob.glob и os.walk, если они не могут быть декодированы (передача в виде строки байтов фактически подавляет необходимость декодирования).

На протяжении всей книги мы будем видеть примеры влияния различий между текстовым и двоичным типами str и bytes в инструментах для работы с файлами: в главах 5 и 12, когда будем исследовать сокеты; в главах 6 и 11, когда нам потребуется игнорировать ошибки Юникода при поиске в файлах и каталогах; в главе 12, когда будем знакомиться с модулями поддержки протоколов Интернета на стороне клиента, таких как FTP и протоколы электронной почты, реализованные поверх сокетов, предполагающих определение режимов файлов и кодировок; и и во многих других местах.

Но так же, как и для строковых типов, в данной главе мы не будем углубляться в эту тему, хотя и будем рассматривать практическое влияние некоторых из представленных концепций. Файлы и строки являются базовой частью языка, и знание их является необходимым условием для чтения этой книги. Как упоминалось ранее, поддержке Юникода посвящена 45-страничная глава в четвертом издании книги «Изучаем Python», поэтому я не буду повторять эти сведения в данной книге. Если при чтении следующих разделов вам покажется, что вы вконец запутались в концепциях, связанных с Юникодом, и в различиях между текстовыми и двоичными строками и файлами, я советую обратиться за более полной информацией к указанной выше книге или к другим источникам.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий