Содержание страницы
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 raiseValueError(or a more codec specific subclass, such asUnicodeEncodeError). 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 raiseValueError(or a more codec specific subclass, such asUnicodeDecodeError). 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:
Значение |
Значение |
|---|---|
|
Возбуждать |
|
Игнорирует символ и продолжает со следующего. |
|
Заменяет подходящим заменяющим символом; для встроенных кодеков Unicode при декодировании Python будет использовать официальный U+FFFD REPLACEMENT CHARACTER, а при кодировании – '?'. |
|
Заменяет соответствующей символьной ссылкой XML (только для кодирования). |
|
Заменяет 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. Объекты IncrementalEncoder¶IncrementalEncoder 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. Объекты IncrementalDecoder¶IncrementalDecoder 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. Объекты StreamWriter¶StreamWriter 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. Объекты StreamReader¶StreamReader 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. Объекты StreamReaderWriter¶StreamReaderWriter Objects
StreamReaderWriter позволяет оборачивать потоки, работающие в режиме
как чтения, так и записи.
Конструкция такова, что для создания экземпляра можно использовать фабричные функции, возвращаемые функцией lookup().
-
class
codecs.StreamReaderWriter(stream, Reader, Writer, errors)¶ Создаёт экземпляр
StreamReaderWriter. поток данных должен быть файлоподобным объектом. Reader и Writer должны быть фабричными функциями или классами, предоставляющими интерфейсыStreamReaderиStreamWriterсоответственно. Обработка ошибок выполняется так же, как определено для читателей и писателей потоков данных.
Экземпляры StreamReaderWriter определяют объединённые интерфейсы классов StreamReader и StreamWriter. Они наследуют все остальные методы и атрибуты от нижележащего потока данных.
7.8.1.7. Объекты StreamRecoder¶StreamRecoder 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 байтам 0x0–0xff. Это означает, что объект 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 и определяют, как эти кодовые точки сопоставляются байтам 0x0–0xff. Чтобы увидеть, как это работает, достаточно открыть, например, 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):
Диапазон |
Кодировка |
|---|---|
|
0xxxxxxx |
|
110xxxxx 10xxxxxx |
|
1110xxxx 10xxxxxx 10xxxxxx |
|
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. Специфические кодировки Python¶Python Specific Encodings
Некоторые предопределенные кодеки специфичны для Python, поэтому их имена кодеков не имеют смысла за пределами Python. Они перечислены в таблицах ниже по типам ожидаемых входных и выходных данных (обратите внимание, что хотя текстовые кодировки являются наиболее распространенным вариантом использования кодеков, базовая инфраструктура кодеков поддерживает произвольные преобразования данных, а не только текстовые кодировки). Для асимметричных кодеков указанное назначение описывает направление кодирования.
Следующие кодеки обеспечивают кодирование из Unicode в str 1 и декодирование из str в Unicode 2, аналогично кодировкам текста Unicode.
Кодек |
Псевдонимы |
Назначение |
|---|---|---|
idna |
Реализует RFC 3490,
см. также
|
|
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 (результат
всегда содержит завершающий |
|
bz2_codec |
bz2 |
Сжимает операнд с помощью bz2 |
|
hex_codec |
hex |
Преобразует операнд в шестнадцатеричное представление, по два разряда на байт |
|
quopri_codec |
quopri, quoted-printable, quotedprintable |
Преобразует операнд в MIME quoted-printable |
|
string_escape |
Создаёт строку, подходящую в качестве строкового литерала в исходном коде Python |
||
uu_codec |
uu |
Преобразует операнд с помощью uuencode |
|
zlib_codec |
zip, zlib |
Сжимает операнд с помощью gzip |
- 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имеет значение истина.
7.8.6. encodings.utf_8_sig – Кодек UTF-8 с сигнатурой BOM¶encodings.utf_8_sig – UTF-8 codec with BOM signature
Новое в версии 2.5.
Этот модуль реализует вариант кодека UTF-8: при кодировании префикс UTF-8 BOM будет добавлен перед байтами, закодированными в UTF-8. Для кодировщика с состоянием это делается только один раз (при первой записи в байтовый поток). При декодировании необязательный UTF-8 BOM в начале данных будет пропущен.