Документация Python неофициальный перевод
Содержание страницы

7.8. codecs – Реестр кодеков и базовые классыcodecs – Codec registry and base classes

Этот модуль определяет базовые классы для стандартных кодеков Python (кодировщиков и декодировщиков) и предоставляет доступ к внутреннему реестру кодеков Python, который управляет процессом поиска кодеков и обработки ошибок.

Он определяет следующие функции:

codecs.encode(obj[, encoding[, errors]])

Кодирует obj с помощью кодека, зарегистрированного для encoding. Кодировка по умолчанию – 'ascii'.

Errors may be given to set the desired error handling scheme. The default error handler is 'strict' meaning that encoding errors raise ValueError (or a more codec specific subclass, such as UnicodeEncodeError). Refer to Codec Base Classes for more information on codec error handling.

Новое в версии 2.4.

codecs.decode(obj[, encoding[, errors]])

Декодирует obj с помощью кодека, зарегистрированного для encoding. Кодировка по умолчанию – 'ascii'.

Errors may be given to set the desired error handling scheme. The default error handler is 'strict' meaning that decoding errors raise ValueError (or a more codec specific subclass, such as UnicodeDecodeError). Refer to Codec Base Classes for more information on codec error handling.

Новое в версии 2.4.

codecs.register(search_function)

Регистрирует функцию поиска кодека. Функции поиска должны принимать один аргумент – имя кодировки строчными буквами, и возвращать объект CodecInfo со следующими атрибутами:

  • name Имя кодировки;

  • encode Функция кодирования без сохранения состояния;

  • decode Функция декодирования без сохранения состояния;

  • incrementalencoder Инкрементальный класс кодировщика или фабричная функция;

  • incrementaldecoder Инкрементальный класс декодировщика или фабричная функция;

  • streamwriter Класс потокового писателя или фабричная функция;

  • streamreader Класс потокового читателя или фабричная функция.

Различные функции или классы принимают следующие аргументы:

encode и decode: это должны быть функции или методы с тем же интерфейсом, что и методы encode()/decode() экземпляров Codec (см. Интерфейс Codec). Ожидается, что функции/методы работают в режиме без сохранения состояния.

incrementalencoder и incrementaldecoder: это должны быть фабричные функции, предоставляющие следующий интерфейс:

factory(errors='strict')

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

streamreader и streamwriter: это должны быть фабричные функции, предоставляющие следующий интерфейс:

factory(stream, errors='strict')

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

Возможные значения параметра errors:

  • 'strict': возбуждать исключение в случае ошибки кодирования

  • 'replace': заменять повреждённые данные подходящим замещающим маркером, например '?' или '\ufffd'

  • 'ignore': игнорировать повреждённые данные и продолжать без дополнительных уведомлений

  • 'xmlcharrefreplace': заменять соответствующей XML-ссылкой на символ (только для кодирования)

  • 'backslashreplace': заменять экранированными последовательностями с обратной косой чертой (только для кодирования)

а также любое другое имя обработчика ошибок, определённое через register_error().

Если функция поиска не может найти заданную кодировку, она должна вернуть None.

codecs.lookup(encoding)

Ищет информацию о кодеке в реестре кодеков Python и возвращает объект CodecInfo, как определено выше.

Сначала кодировки ищутся в кэше реестра. Если не найдены, просматривается список зарегистрированных функций поиска. Если объект CodecInfo не найден, вызывается LookupError. В противном случае объект CodecInfo сохраняется в кэше и возвращается вызывающему.

Для упрощения доступа к различным кодекам модуль предоставляет следующие дополнительные функции, которые используют lookup() для поиска кодека:

codecs.getencoder(encoding)

Находит кодек для указанной кодировки и возвращает его функцию-кодировщик.

Вызывает LookupError, если кодировка не найдена.

codecs.getdecoder(encoding)

Находит кодек для указанной кодировки и возвращает его функцию-декодер.

Вызывает LookupError, если кодировка не найдена.

codecs.getincrementalencoder(encoding)

Находит кодек для указанной кодировки и возвращает его класс инкрементального кодировщика или фабричную функцию.

Вызывает LookupError, если кодировка не найдена или кодек не поддерживает инкрементальный кодировщик.

Новое в версии 2.5.

codecs.getincrementaldecoder(encoding)

Находит кодек для указанной кодировки и возвращает его класс инкрементального декодера или фабричную функцию.

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

Новое в версии 2.5.

codecs.getreader(encoding)

Находит кодек для указанной кодировки и возвращает его класс StreamReader или фабричную функцию.

Вызывает LookupError, если кодировка не найдена.

codecs.getwriter(encoding)

Находит кодек для указанной кодировки и возвращает его класс StreamWriter или фабричную функцию.

Вызывает LookupError, если кодировка не найдена.

codecs.register_error(name, error_handler)

Регистрирует функцию обработки ошибок error_handler под именем name. error_handler будет вызываться при кодировании и декодировании в случае ошибки, когда name указан как параметр errors.

При кодировании error_handler будет вызван с экземпляром UnicodeEncodeError, который содержит информацию о местоположении ошибки. Обработчик ошибок должен либо возбудить это же или другое исключение, либо вернуть кортеж с заменой для некодируемой части входных данных и позицией, с которой следует продолжить кодирование. Кодировщик закодирует замену и продолжит кодирование исходного ввода с указанной позиции. Отрицательные значения позиции трактуются как относительные от конца входной строки. Если результирующая позиция выходит за границы, будет возбуждено IndexError.

Декодирование и трансляция работают аналогично, за исключением того, что обработчику будет передан UnicodeDecodeError или UnicodeTranslateError, и что замена от обработчика ошибок будет помещена в вывод напрямую.

codecs.lookup_error(name)

Возвращает обработчик ошибок, ранее зарегистрированный под именем name.

Выбрасывает LookupError, если обработчик не найден.

codecs.strict_errors(exception)

Реализует обработку ошибок strict: каждая ошибка кодирования или декодирования возбуждает UnicodeError.

codecs.replace_errors(exception)

Реализует обработку ошибок replace: повреждённые данные заменяются подходящим замещающим символом, таким как '?' в байтовых строках и '\ufffd' в строках Unicode.

codecs.ignore_errors(exception)

Реализует обработку ошибок ignore: повреждённые данные игнорируются, и кодирование или декодирование продолжается без дополнительных уведомлений.

codecs.xmlcharrefreplace_errors(exception)

Реализует обработку ошибок xmlcharrefreplace (только для кодирования): не кодируемый символ заменяется соответствующей XML-ссылкой на символ.

codecs.backslashreplace_errors(exception)

Реализует обработку ошибок backslashreplace (только для кодирования): не кодируемый символ заменяется управляющей последовательностью с обратной косой чертой.

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

codecs.open(filename, mode[, encoding[, errors[, buffering]]])

Открывает закодированный файл, используя заданный режим, и возвращает обёрнутую версию, обеспечивающую прозрачное кодирование/декодирование. Режим файла по умолчанию – 'r', то есть файл открывается в режиме чтения.

Примечание

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

Примечание

Файлы всегда открываются в двоичном режиме, даже если двоичный режим не был указан. Это сделано для предотвращения потери данных из-за кодировок, использующих 8-битные значения. Это означает, что при чтении и записи не выполняется автоматическое преобразование '\n'.

encoding задаёт кодировку, которая будет использоваться для файла.

Параметр errors можно задать для определения обработки ошибок. По умолчанию он равен 'strict', что приводит к возбуждению ValueError при возникновении ошибки кодирования.

buffering имеет то же значение, что и для встроенной функции open(). По умолчанию используется построчная буферизация.

codecs.EncodedFile(file, input[, output[, errors]])

Возвращает обёрнутую версию файла, которая обеспечивает прозрачное преобразование кодировки.

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

Если output не задан, по умолчанию используется input.

errors может быть задан для определения обработки ошибок. По умолчанию 'strict', что приводит к возбуждению ValueError в случае ошибки кодирования.

codecs.iterencode(iterable, encoding[, errors])

Использует инкрементальный кодировщик для последовательного кодирования входных данных из iterable. Эта функция является генератором. Параметр errors (а также любые другие именованные аргументы) передаётся инкрементальному кодировщику.

Новое в версии 2.5.

codecs.iterdecode(iterable, encoding[, errors])

Использует инкрементальный декодировщик для последовательного декодирования входных данных из iterable. Эта функция является генератором. Параметр errors (а также любые другие именованные аргументы) передаётся инкрементальному декодировщику.

Новое в версии 2.5.

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

codecs.BOM
codecs.BOM_BE
codecs.BOM_LE
codecs.BOM_UTF8
codecs.BOM_UTF16
codecs.BOM_UTF16_BE
codecs.BOM_UTF16_LE
codecs.BOM_UTF32
codecs.BOM_UTF32_BE
codecs.BOM_UTF32_LE

Эти константы определяют различные кодировки метки порядка байтов (BOM) Unicode, используемые в потоках данных UTF-16 и UTF-32 для указания порядка байтов в потоке или файле, а в UTF-8 – как сигнатура Unicode. BOM_UTF16 – это либо BOM_UTF16_BE, либо BOM_UTF16_LE в зависимости от нативного порядка байтов платформы, BOM – псевдоним для BOM_UTF16, BOM_LE – для BOM_UTF16_LE и BOM_BE – для BOM_UTF16_BE. Остальные представляют BOM в кодировках UTF-8 и UTF-32.

7.8.1. Базовые классы кодековCodec Base Classes

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

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

Класс Codec определяет интерфейс для кодеров/декодеров без состояния.

Для упрощения и стандартизации обработки ошибок методы encode() и decode() могут реализовывать различные схемы обработки ошибок, принимая строковый аргумент errors. Следующие строковые значения определены и реализованы во всех стандартных кодеках Python:

Значение

Значение

'strict'

Возбуждать UnicodeError (или подкласс); это поведение по умолчанию.

'ignore'

Игнорирует символ и продолжает со следующего.

'replace'

Заменяет подходящим заменяющим символом; для встроенных кодеков Unicode при декодировании Python будет использовать официальный U+FFFD REPLACEMENT CHARACTER, а при кодировании – '?'.

'xmlcharrefreplace'

Заменяет соответствующей символьной ссылкой XML (только для кодирования).

'backslashreplace'

Заменяет escape-последовательностями с обратной косой чертой (только для кодирования).

Набор допустимых значений может быть расширен с помощью register_error().

7.8.1.1. Объекты кодековCodec Objects

Класс Codec определяет следующие методы, которые также задают функциональные интерфейсы кодера и декодера без состояния:

Codec.encode(input[, errors])

Кодирует объект input и возвращает кортеж (выходной объект, количество использованных символов). Хотя кодеки не ограничены использованием с Unicode, в контексте Unicode кодирование преобразует объект Unicode в простую строку с использованием определённой кодировки набора символов (например, cp1252 или iso-8859-1).

errors определяет применяемую обработку ошибок. По умолчанию используется обработка 'strict'.

Метод не должен сохранять состояние в экземпляре Codec. Используйте StreamWriter для кодеков, которым необходимо сохранять состояние для эффективного кодирования.

Кодировщик должен уметь обрабатывать входные данные нулевой длины и в этом случае возвращать пустой объект типа объекта вывода.

Codec.decode(input[, errors])

Декодирует объект input и возвращает кортеж (выходной объект, количество использованных символов). В контексте Unicode декодирование преобразует простую строку, закодированную с использованием определённой кодировки набора символов, в объект Unicode.

input должен быть объектом, который предоставляет слот буфера bf_getreadbuf. Строки Python, буферные объекты и файлы, отображённые в память, являются примерами объектов, предоставляющих этот слот.

errors определяет применяемую обработку ошибок. По умолчанию используется обработка 'strict'.

Метод не должен сохранять состояние в экземпляре Codec. Используйте StreamReader для кодеков, которым необходимо сохранять состояние для эффективного декодирования.

Декодировщик должен уметь обрабатывать входные данные нулевой длины и в этом случае возвращать пустой объект типа объекта вывода.

Классы IncrementalEncoder и IncrementalDecoder предоставляют базовый интерфейс для инкрементального кодирования и декодирования. Кодирование/декодирование входных данных выполняется не одним вызовом функции кодировщика/декодировщика без состояния, а несколькими вызовами метода encode()/decode() инкрементального кодировщика/декодировщика. Инкрементальный кодировщик/декодировщик отслеживает процесс кодирования/декодирования во время вызовов методов.

Объединённый вывод вызовов метода encode()/decode() совпадает с тем, что получилось бы, если бы все отдельные входные данные были объединены в один, и этот вход был закодирован/декодирован кодировщиком/декодировщиком без состояния.

7.8.1.2. Объекты IncrementalEncoderIncrementalEncoder Objects

Новое в версии 2.5.

Класс IncrementalEncoder используется для кодирования входных данных за несколько шагов. Он определяет следующие методы, которые должен реализовать любой инкрементальный кодировщик для совместимости с реестром кодеков Python.

class codecs.IncrementalEncoder([errors])

Конструктор экземпляра IncrementalEncoder.

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

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

  • 'strict' Возбуждать ValueError (или подкласс); это по умолчанию.

  • 'ignore' Игнорировать символ и продолжить со следующим.

  • 'replace' Заменить подходящим заменяющим символом

  • 'xmlcharrefreplace' Заменить соответствующей XML-ссылкой на символ

  • 'backslashreplace' Заменить управляющими последовательностями с обратной косой чертой.

Аргумент errors будет присвоен атрибуту с тем же именем. Присваивание этому атрибуту позволяет переключаться между разными стратегиями обработки ошибок в течение времени жизни объекта IncrementalEncoder.

Набор допустимых значений для аргумента errors можно расширить с помощью register_error().

encode(object[, final])

Кодирует object (с учётом текущего состояния кодировщика) и возвращает результирующий закодированный объект. Если это последний вызов encode(), final должен быть истинным (по умолчанию – ложь).

reset()

Сбрасывает кодировщик в начальное состояние.

7.8.1.3. Объекты IncrementalDecoderIncrementalDecoder Objects

Класс IncrementalDecoder используется для декодирования входных данных за несколько шагов. Он определяет следующие методы, которые должен реализовать любой инкрементальный декодер для совместимости с реестром кодеков Python.

class codecs.IncrementalDecoder([errors])

Конструктор экземпляра IncrementalDecoder.

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

IncrementalDecoder может реализовывать разные схемы обработки ошибок с помощью ключевого аргумента errors. Доступны следующие параметры:

  • 'strict' Возбуждает ValueError (или подкласс); используется по умолчанию.

  • 'ignore' Пропускает символ и переходит к следующему.

  • 'replace' Заменяет подходящим символом-заменителем.

Аргумент errors будет присвоен атрибуту с тем же именем. Присваивание этому атрибуту позволяет переключаться между разными стратегиями обработки ошибок в течение времени жизни объекта IncrementalDecoder.

Набор допустимых значений для аргумента errors можно расширить с помощью register_error().

decode(object[, final])

Декодирует object (с учётом текущего состояния декодера) и возвращает результирующий декодированный объект. Если это последний вызов decode(), final должен быть истинным (по умолчанию – ложь). Если final истинно, декодер должен полностью декодировать входные данные и сбросить все буферы. Если это невозможно (например, из-за неполных последовательностей байтов в конце входных данных), он должен инициировать обработку ошибок, как в случае без сохранения состояния (что может вызвать исключение).

reset()

Сбрасывает декодер в исходное состояние.

Классы StreamWriter и StreamReader предоставляют универсальные рабочие интерфейсы, которые можно использовать для очень простой реализации новых подмодулей кодирования. Пример см. в encodings.utf_8.

7.8.1.4. Объекты StreamWriterStreamWriter Objects

Класс StreamWriter является подклассом Codec и определяет следующие методы, которые каждый потоковый писатель должен реализовать для совместимости с реестром кодеков Python.

class codecs.StreamWriter(stream[, errors])

Конструктор экземпляра StreamWriter.

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

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

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

  • 'strict' Возбуждает ValueError (или подкласс); используется по умолчанию.

  • 'ignore' Пропускает символ и переходит к следующему.

  • 'replace' Заменяет подходящим символом-заменителем

  • 'xmlcharrefreplace' Заменяет соответствующей ссылкой на символ XML

  • 'backslashreplace' Заменяет экранированными последовательностями с обратной косой чертой.

Аргумент errors будет присвоен атрибуту с тем же именем. Присваивание этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение времени жизни объекта StreamWriter.

Набор допустимых значений для аргумента errors можно расширить с помощью register_error().

write(object)

Записывает в поток закодированное содержимое объекта.

writelines(list)

Записывает в поток объединённый список строк (возможно, переиспользуя метод write()).

reset()

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

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

В дополнение к приведённым выше методам, StreamWriter также должен наследовать все остальные методы и атрибуты от нижележащего потока данных.

7.8.1.5. Объекты StreamReaderStreamReader Objects

Класс StreamReader является подклассом Codec и определяет следующие методы, которые каждый потоковый читатель должен реализовать для совместимости с реестром кодеков Python.

class codecs.StreamReader(stream[, errors])

Конструктор экземпляра StreamReader.

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

поток данных должен быть файлоподобным объектом, открытым для чтения (двоичных) данных.

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

  • 'strict' Возбуждает ValueError (или подкласс); используется по умолчанию.

  • 'ignore' Пропускает символ и переходит к следующему.

  • 'replace' Заменяет подходящим символом-заменителем.

Аргумент errors будет присвоен атрибуту с тем же именем. Присваивание этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение времени жизни объекта StreamReader.

Набор допустимых значений для аргумента errors можно расширить с помощью register_error().

read([size[, chars[, firstline]]])

Декодирует данные из потока и возвращает результирующий объект.

chars указывает количество читаемых из потока символов. read() никогда не вернёт больше chars символов, но может вернуть меньше, если доступно недостаточно символов.

size указывает приблизительное максимальное количество байт для чтения из потока данных в целях декодирования. Декодер может изменять этот параметр по своему усмотрению. Значение по умолчанию -1 означает, что нужно читать и декодировать как можно больше. size предназначен для того, чтобы избежать декодирования огромных файлов за один шаг.

firstline указывает, что достаточно вернуть только первую строку, если на последующих строках возникают ошибки декодирования.

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

Изменено в версии 2.4: добавлен аргумент chars.

Изменено в версии 2.4.2: добавлен аргумент firstline.

readline([size[, keepends]])

Читает одну строку из входного потока и возвращает декодированные данные.

size, если задан, передаётся как аргумент size в метод read() потока данных.

Если keepends равен False, из возвращаемых строк будут удалены символы конца строки.

Изменено в версии 2.4: добавлен аргумент keepends.

readlines([sizehint[, keepends]])

Читает все строки из входного потока данных и возвращает их в виде списка строк.

Окончания строк реализуются с помощью метода декодера кодека и включаются в элементы списка, если keepends имеет значение true.

sizehint, если задан, передаётся как аргумент size в метод read() потока данных.

reset()

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

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

В дополнение к приведённым выше методам, StreamReader также должен наследовать все остальные методы и атрибуты от нижележащего потока данных.

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

7.8.1.6. Объекты StreamReaderWriterStreamReaderWriter Objects

StreamReaderWriter позволяет оборачивать потоки, работающие в режиме как чтения, так и записи.

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

class codecs.StreamReaderWriter(stream, Reader, Writer, errors)

Создаёт экземпляр StreamReaderWriter. поток данных должен быть файлоподобным объектом. Reader и Writer должны быть фабричными функциями или классами, предоставляющими интерфейсы StreamReader и StreamWriter соответственно. Обработка ошибок выполняется так же, как определено для читателей и писателей потоков данных.

Экземпляры StreamReaderWriter определяют объединённые интерфейсы классов StreamReader и StreamWriter. Они наследуют все остальные методы и атрибуты от нижележащего потока данных.

7.8.1.7. Объекты StreamRecoderStreamRecoder Objects

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

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

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)

Создаёт экземпляр StreamRecoder, реализующий двунаправленное преобразование: encode и decode работают на внешнем уровне (вход read() и выход write()), а Reader и Writer – на внутреннем (чтение и запись в поток).

Эти объекты можно использовать для прозрачного прямого перекодирования, например, из Latin-1 в UTF-8 и обратно.

Поток данных должен быть файлоподобным объектом.

encode и decode должны соответствовать интерфейсу Codec. Reader, Writer должны быть фабричными функциями или классами, предоставляющими объекты интерфейсов StreamReader и StreamWriter соответственно.

encode и decode нужны для преобразования на внешнем уровне, а Reader и Writer – на внутреннем. Используемый промежуточный формат определяется двумя наборами кодеков; например, кодеки Unicode будут использовать Unicode как промежуточную кодировку.

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

Экземпляры StreamRecoder определяют объединённые интерфейсы классов StreamReader и StreamWriter. Они наследуют все остальные методы и атрибуты от нижележащего потока данных.

7.8.2. Кодировки и ЮникодEncodings and Unicode

Строки Unicode внутри хранятся как последовательности кодовых точек (если точнее, как массивы Py_UNICODE). В зависимости от того, как собран Python (через --enable-unicode=ucs2 или --enable-unicode=ucs4, причём первое используется по умолчанию), Py_UNICODE может быть 16-битным или 32-битным типом данных. Когда объект Unicode используется за пределами CPU и памяти, порядок байт (endianness) и способ хранения массивов в виде байтов становятся важными. Преобразование объекта Unicode в последовательность байтов называется кодированием, а восстановление объекта Unicode из последовательности байтов – декодированием. Существует много различных способов такого преобразования (они также называются кодировками). Простейший метод – сопоставить кодовые точки 0–255 байтам 0x00xff. Это означает, что объект Unicode, содержащий кодовые точки выше U+00FF, нельзя закодировать этим методом (который называется 'latin-1' или 'iso-8859-1'). unicode.encode() возбудит исключение UnicodeEncodeError, которое выглядит так: UnicodeEncodeError: 'latin-1' codec can't encode character u'\u1234' in position 3: ordinal not in range(256).

Существует ещё одна группа кодировок (так называемые charmap-кодировки), которые выбирают другое подмножество всех кодовых точек Unicode и определяют, как эти кодовые точки сопоставляются байтам 0x00xff. Чтобы увидеть, как это работает, достаточно открыть, например, encodings/cp1252.py (это кодировка, используемая в основном в Windows). Там есть строковая константа из 256 символов, показывающая, какой символ какому значению байта соответствует.

Все эти кодировки могут закодировать лишь 256 из 1114112 кодовых точек, определённых в Unicode. Простой и прямой способ, позволяющий хранить каждую кодовую точку Unicode, – хранить каждую кодовую точку как четыре последовательных байта. Есть две возможности: хранить байты в порядке big endian или little endian. Эти две кодировки называются UTF-32-BE и UTF-32-LE соответственно. Их недостаток в том, что если, например, использовать UTF-32-BE на little endian-машине, то всегда придётся менять порядок байтов при кодировании и декодировании. UTF-32 избегает этой проблемы: байты всегда будут располагаться в естественном порядке. Однако при чтении этих байтов CPU с другим порядком байтов их придётся переставлять. Чтобы иметь возможность определить порядок байтов последовательности UTF-16 или UTF-32, существует так называемая BOM (метка порядка байтов). Это символ Unicode U+FEFF. Этот символ может добавляться в начало каждой последовательности байтов UTF-16 или UTF-32. Версия этого символа с переставленными байтами (0xFFFE) является недопустимым символом, который не должен встречаться в тексте Unicode. Таким образом, когда первый символ в последовательности UTF-16 или UTF-32 оказывается U+FFFE, байты необходимо переставить при декодировании. К сожалению, символ U+FEFF имел и второе назначение как ZERO WIDTH NO-BREAK SPACE: символ, не имеющий ширины и не позволяющий разбивать слово. Его можно использовать, например, для подсказок алгоритму лигатур. Начиная с Unicode 4.0 использование U+FEFF в качестве ZERO WIDTH NO-BREAK SPACE считается устаревшим (эту роль взял на себя U+2060 (WORD JOINER)). Тем не менее, программное обеспечение Unicode по-прежнему должно уметь обрабатывать U+FEFF в обеих ролях: как BOM это средство определения порядка хранения закодированных байтов, которое исчезает после декодирования последовательности в строку Unicode; как ZERO WIDTH NO-BREAK SPACE это обычный символ, который декодируется как любой другой.

Существует ещё одна кодировка, способная кодировать весь диапазон символов Unicode: UTF-8. UTF-8 – это 8-битная кодировка, а это значит, что в UTF-8 нет проблем с порядком байтов. Каждый байт в последовательности UTF-8 состоит из двух частей: битов маркера (самые старшие биты) и битов полезной нагрузки. Биты маркера представляют собой последовательность от нуля до четырёх битов 1, за которой следует бит 0. Символы Unicode кодируются следующим образом (где x – биты полезной нагрузки, которые при объединении дают символ Unicode):

Диапазон

Кодировка

U-00000000U-0000007F

0xxxxxxx

U-00000080U-000007FF

110xxxxx 10xxxxxx

U-00000800U-0000FFFF

1110xxxx 10xxxxxx 10xxxxxx

U-00010000U-0010FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Младший значащий бит символа Unicode – это самый правый бит x.

Поскольку UTF-8 – это 8-битная кодировка, BOM не требуется, и любой U+FEFF символ в dекодированной строке Unicode (даже если это первый символ) рассматривается как ZERO WIDTH NO-BREAK SPACE.

Без дополнительной информации невозможно надёжно определить, какая кодировка использовалась для кодирования строки Unicode. Любая charmap-кодировка может декодировать любую произвольную последовательность байт. Однако с UTF-8 это невозможно, так как байтовые последовательности UTF-8 имеют структуру, не допускающую произвольных последовательностей. Чтобы повысить надёжность определения кодировки UTF-8, Microsoft изобрела вариант UTF-8 (который Python 2.5 называет "utf-8-sig") для своей программы Notepad: перед тем как любой символ Unicode записывается в файл, записывается BOM в кодировке UTF-8 (который выглядит как последовательность байт: 0xef, 0xbb, 0xbf). Поскольку маловероятно, что какой-либо файл в charmap-кодировке начинается с таких значений байт (которые, например, отображаются в

ЛАТИНСКАЯ СТРОЧНАЯ БУКВА I С ДИЭРЕЗИСОМ
ПРАВАЯ ДВОЙНАЯ УГЛОВАЯ КАВЫЧКА
ПЕРЕВЁРНУТЫЙ ВОПРОСИТЕЛЬНЫЙ ЗНАК

в iso-8859-1) это увеличивает вероятность того, что кодировка utf-8-sig может быть правильно определена по последовательности байтов. Таким образом, здесь BOM используется не для определения порядка байтов, используемого при формировании последовательности байтов, а как сигнатура, помогающая угадать кодировку. При кодировании кодек utf-8-sig запишет 0xef, 0xbb, 0xbf как первые три байта в файл. При декодировании utf-8-sig пропустит эти три байта, если они стоят в начале файла. В UTF-8 использование BOM не рекомендуется и, как правило, его следует избегать.

7.8.3. Стандартные кодировкиStandard Encodings

Python поставляется с рядом встроенных кодеков, реализованных либо как функции на C либо с использованием словарей в качестве таблиц сопоставления. В следующей таблице перечислены кодеки по имени, а также некоторые распространённые псевдонимы и языки, для которых вероятно используется данная кодировка. Ни список псевдонимов, ни список языков не является исчерпывающим. Обратите внимание, что альтернативные написания, различающиеся только регистром или использующие дефис вместо подчёркивания, также являются допустимыми псевдонимами; поэтому, например, 'utf-8' является допустимым псевдонимом для кодека 'utf_8'.

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

  • набор символов ISO 8859

  • кодовая страница Microsoft Windows, которая обычно происходит из набора 8859, но заменяет управляющие символы дополнительными графическими символами

  • кодовая страница IBM EBCDIC

  • кодовая страница IBM PC, совместимая с ASCII

Кодек

Псевдонимы

Языки

ascii

646, us-ascii

Английский

big5

big5-tw, csbig5

Китайский традиционный

big5hkscs

big5-hkscs, hkscs

Китайский традиционный

cp037

IBM037, IBM039

Английский

cp424

EBCDIC-CP-HE, IBM424

Иврит

cp437

437, IBM437

Английский

cp500

EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500

Западная Европа

cp720

Арабский

cp737

Греческий

cp775

IBM775

Балтийские языки

cp850

850, IBM850

Западная Европа

cp852

852, IBM852

Центральная и Восточная Европа

cp855

855, IBM855

болгарский, белорусский, македонский, русский, сербский

cp856

Иврит

cp857

857, IBM857

Турецкий

cp858

858, IBM858

Западная Европа

cp860

860, IBM860

португальский

cp861

861, CP-IS, IBM861

Исландский

cp862

862, IBM862

Иврит

cp863

863, IBM863

канадский

cp864

IBM864

Арабский

cp865

865, IBM865

датский, норвежский

cp866

866, IBM866

Русский

cp869

869, CP-GR, IBM869

Греческий

cp874

Тайский

cp875

Греческий

cp932

932, ms932, mskanji, ms-kanji

Японский

cp949

949, ms949, uhc

Корейский

cp950

950, ms950

Китайский традиционный

cp1006

Урду

cp1026

ibm1026

Турецкий

cp1140

ibm1140

Западная Европа

cp1250

windows-1250

Центральная и Восточная Европа

cp1251

windows-1251

болгарский, белорусский, македонский, русский, сербский

cp1252

windows-1252

Западная Европа

cp1253

windows-1253

Греческий

cp1254

windows-1254

Турецкий

cp1255

windows-1255

Иврит

cp1256

windows-1256

Арабский

cp1257

windows-1257

Балтийские языки

cp1258

windows-1258

вьетнамский

euc_jp

eucjp, ujis, u-jis

Японский

euc_jis_2004

jisx0213, eucjis2004

Японский

euc_jisx0213

eucjisx0213

Японский

euc_kr

euckr, корейский, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001

Корейский

gb2312

chinese, csiso58gb231280, euc- cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso- ir-58

Упрощённый китайский

gbk

936, cp936, ms936

Унифицированный китайский

gb18030

gb18030-2000

Унифицированный китайский

hz

hzgb, hz-gb, hz-gb-2312

Упрощённый китайский

iso2022_jp

csiso2022jp, iso2022jp, iso-2022-jp

Японский

iso2022_jp_1

iso2022jp-1, iso-2022-jp-1

Японский

iso2022_jp_2

iso2022jp-2, iso-2022-jp-2

Японский, корейский, упрощённый китайский, западноевропейские языки, греческий

iso2022_jp_2004

iso2022jp-2004, iso-2022-jp-2004

Японский

iso2022_jp_3

iso2022jp-3, iso-2022-jp-3

Японский

iso2022_jp_ext

iso2022jp-ext, iso-2022-jp-ext

Японский

iso2022_kr

csiso2022kr, iso2022kr, iso-2022-kr

Корейский

latin_1

iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1

Западная Европа

iso8859_2

iso-8859-2, latin2, L2

Центральная и Восточная Европа

iso8859_3

iso-8859-3, latin3, L3

Эсперанто, мальтийский

iso8859_4

iso-8859-4, latin4, L4

Балтийские языки

iso8859_5

iso-8859-5, кириллица

болгарский, белорусский, македонский, русский, сербский

iso8859_6

iso-8859-6, арабский

Арабский

iso8859_7

iso-8859-7, греческий, greek8

Греческий

iso8859_8

iso-8859-8, иврит

Иврит

iso8859_9

iso-8859-9, latin5, L5

Турецкий

iso8859_10

iso-8859-10, latin6, L6

Скандинавские языки

iso8859_11

iso-8859-11, тайская

Тайские языки

iso8859_13

iso-8859-13, latin7, L7

Балтийские языки

iso8859_14

iso-8859-14, latin8, L8

Кельтские языки

iso8859_15

iso-8859-15, latin9, L9

Западная Европа

iso8859_16

iso-8859-16, latin10, L10

Юго-Восточная Европа

johab

cp1361, ms1361

Корейский

koi8_r

Русский

koi8_u

Украинский

mac_cyrillic

maccyrillic

болгарский, белорусский, македонский, русский, сербский

mac_greek

macgreek

Греческий

mac_iceland

maciceland

Исландский

mac_latin2

maclatin2, maccentraleurope

Центральная и Восточная Европа

mac_roman

macroman

Западная Европа

mac_turkish

macturkish

Турецкий

ptcp154

csptcp154, pt154, cp154, cyrillic-asian

Казахский

shift_jis

csshiftjis, shiftjis, sjis, s_jis

Японский

shift_jis_2004

shiftjis2004, sjis_2004, sjis2004

Японский

shift_jisx0213

shiftjisx0213, sjisx0213, s_jisx0213

Японский

utf_32

U32, utf32

все языки

utf_32_be

UTF-32BE

все языки

utf_32_le

UTF-32LE

все языки

utf_16

U16, utf16

все языки

utf_16_be

UTF-16BE

все языки (только BMP)

utf_16_le

UTF-16LE

все языки (только BMP)

utf_7

U7, unicode-1-1-utf-7

все языки

utf_8

U8, UTF, utf8

все языки

utf_8_sig

все языки

7.8.4. Специфические кодировки PythonPython Specific Encodings

Некоторые предопределенные кодеки специфичны для Python, поэтому их имена кодеков не имеют смысла за пределами Python. Они перечислены в таблицах ниже по типам ожидаемых входных и выходных данных (обратите внимание, что хотя текстовые кодировки являются наиболее распространенным вариантом использования кодеков, базовая инфраструктура кодеков поддерживает произвольные преобразования данных, а не только текстовые кодировки). Для асимметричных кодеков указанное назначение описывает направление кодирования.

Следующие кодеки обеспечивают кодирование из Unicode в str 1 и декодирование из str в Unicode 2, аналогично кодировкам текста Unicode.

Кодек

Псевдонимы

Назначение

idna

Реализует RFC 3490, см. также encodings.idna

mbcs

dbcs

Только Windows: кодирует операнд в соответствии с кодовой страницей ANSI (CP_ACP).

palmos

Кодировка PalmOS 3.5

punycode

Реализует RFC 3492

raw_unicode_escape

Создаёт строку, пригодную для использования в качестве сырого Unicode-литерала в исходном коде Python

rot_13

rot13

Возвращает шифрование Цезаря операнда

undefined

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

unicode_escape

Создаёт строку, пригодную для использования в качестве Unicode-литерала в исходном коде Python

unicode_internal

Возвращает внутреннее представление операнда

Новое в версии 2.3: Кодировки idna и punycode.

Следующие кодеки обеспечивают кодирование и декодирование из строки в строку 2.

Кодек

Псевдонимы

Назначение

Кодировщик/декодировщик

base64_codec

base64, base-64

Преобразует операнд в многолинейный MIME base64 (результат всегда содержит завершающий '\n')

base64.encodestring(), base64.decodestring()

bz2_codec

bz2

Сжимает операнд с помощью bz2

bz2.compress(), bz2.decompress()

hex_codec

hex

Преобразует операнд в шестнадцатеричное представление, по два разряда на байт

binascii.b2a_hex(), binascii.a2b_hex()

quopri_codec

quopri, quoted-printable, quotedprintable

Преобразует операнд в MIME quoted-printable

quopri.encode() с quotetabs=True, quopri.decode()

string_escape

Создаёт строку, подходящую в качестве строкового литерала в исходном коде Python

uu_codec

uu

Преобразует операнд с помощью uuencode

uu.encode(), uu.decode()

zlib_codec

zip, zlib

Сжимает операнд с помощью gzip

zlib.compress(), zlib.decompress()

1

Объекты str также принимаются в качестве входных данных вместо объектов unicode. Они неявно преобразуются в unicode путём декодирования с использованием кодировки по умолчанию. Если это преобразование не удаётся, операции кодирования могут вызвать UnicodeDecodeError.

2(1,2)

Объекты unicode также принимаются в качестве входных данных вместо объектов str. Они неявно преобразуются в str путём кодирования с использованием кодировки по умолчанию. Если это преобразование не удаётся, операции декодирования могут вызвать UnicodeEncodeError.

7.8.5. encodings.idna – Интернационализированные доменные имена в приложенияхencodings.idna – Internationalized Domain Names in Applications

Новое в версии 2.3.

Этот модуль реализует RFC 3490 (Internationalized Domain Names in Applications) и RFC 3492 (Nameprep: профиль Stringprep для интернационализированных доменных имен (IDN)). Он основан на кодировке punycode и stringprep.

Эти RFC совместно определяют протокол для поддержки не-ASCII символов в доменных именах. Доменное имя, содержащее не-ASCII символы (например, www.Alliancefrançaise.nu), преобразуется в ASCII-совместимую кодировку (ACE, такую как www.xn--alliancefranaise-npb.nu). Форма ACE доменного имени затем используется во всех местах, где протокол не допускает произвольных символов, таких как DNS-запросы, поля HTTP Host и так далее. Это преобразование выполняется в приложении; по возможности незаметно для пользователя: приложение должно прозрачно преобразовывать метки доменов Unicode в IDNA при передаче по сети и преобразовывать обратно метки ACE в Unicode перед представлением их пользователю.

Python поддерживает это преобразование несколькими способами: кодек idna выполняет преобразование между Unicode и ACE, разделяя входную строку на метки на основе символов-разделителей, определённых в разделе 3.1 (1) документа RFC 3490 и преобразуя каждую метку в ACE по мере необходимости, и, наоборот, разделяя входную байтовую строку на метки на основе разделителя . и преобразуя найденные метки ACE в Unicode. Кроме того, модуль socket прозрачно преобразует Unicode-имена хостов в ACE, так что приложениям не нужно заботиться о преобразовании имён хостов при передаче их модулю socket. Вдобавок модули, которые принимают имена хостов в качестве параметров функций, такие как httplib и ftplib, принимают Unicode-имена хостов (httplib также прозрачно отправляет имя хоста в формате IDNA в поле Host, если оно вообще отправляет это поле).

При получении имён хостов из сети (например, при обратном поиске имени) автоматическое преобразование в Unicode не выполняется: приложения, желающие отобразить такие имена хостов пользователю, должны декодировать их в Unicode.

Модуль encodings.idna также реализует процедуру nameprep, которая выполняет определённые нормализации имён хостов для достижения нечувствительности к регистру интернационализированных доменных имён и унификации похожих символов. Функции nameprep можно использовать напрямую, если необходимо.

encodings.idna.nameprep(label)

Возвращает версию label после обработки nameprep. В текущей реализации предполагаются строки запроса, поэтому AllowUnassigned имеет значение истина.

encodings.idna.ToASCII(label)

Преобразует метку в ASCII, как указано в RFC 3490. Предполагается, что UseSTD3ASCIIRules имеет значение false.

encodings.idna.ToUnicode(label)

Преобразует метку в Unicode, как указано в RFC 3490.

7.8.6. encodings.utf_8_sig – Кодек UTF-8 с сигнатурой BOMencodings.utf_8_sig – UTF-8 codec with BOM signature

Новое в версии 2.5.

Этот модуль реализует вариант кодека UTF-8: при кодировании префикс UTF-8 BOM будет добавлен перед байтами, закодированными в UTF-8. Для кодировщика с состоянием это делается только один раз (при первой записи в байтовый поток). При декодировании необязательный UTF-8 BOM в начале данных будет пропущен.