Как называется библиотека Python, предназначенная для работы с файлами в различных кодировках

Обновлено: 01.07.2024

В этом руководстве мы узнаем о методе Python String encode() с помощью примеров.

Метод encode() возвращает закодированную версию данной строки.

Пример

Синтаксис строки encode()

Синтаксис метода encode():

Параметры строки encode()

По умолчанию метод encode() не требует никаких параметров.

Он возвращает версию строки в кодировке utf-8. В случае сбоя возникает исключение UnicodeDecodeError.

Однако он принимает два параметра:

  • кодировка – тип кодировки, в который должна быть закодирована строка.
  • ошибки — ответ при сбое кодирования. Существует шесть типов ответа на ошибку
    • строгий – ответ по умолчанию, вызывающий исключение UnicodeDecodeError в случае сбоя.
    • игнорировать – игнорирует некодируемый юникод из результата.
    • replace — заменяет некодируемый юникод на вопросительный знак ?
    • xmlcharrefreplace – вставляет ссылку на символ XML вместо некодируемого юникода.
    • backslashreplace – вставляет escape-последовательность \uNNNN вместо некодируемого юникода.
    • namereplace – вставляет escape-последовательность \N вместо некодируемого юникода.

    Пример 1: кодирование в кодировку Utf-8 по умолчанию

    Вывод

    Пример 2: Кодирование с параметром ошибки

    Вывод

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

    Кодировка строк

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

    Для эффективного хранения этих строк последовательность кодовых точек преобразуется в набор байтов. Этот процесс называется кодированием.

    Существуют различные кодировки, которые по-разному обрабатывают строку. Популярные кодировки: utf-8, ascii и т. д.

    Используя метод string encode(), вы можете преобразовывать строки Unicode в любые кодировки, поддерживаемые Python. По умолчанию Python использует кодировку utf-8.

    Недавнее обсуждение в списке рассылки python-ideas показало, что нам (то есть основным разработчикам Python) необходимо предоставить более четкое руководство о том, как обрабатывать задачи обработки текста, которые по умолчанию вызывают исключения в Python 3, но ранее заметен под ковер беспечным предположением Python 2 о том, что все файлы закодированы в «latin-1».

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

    Что изменилось в Python 3?¶

    Очевидный вопрос: что изменилось в Python 3, так что распространенные подходы, которые разработчики использовали для обработки текста в Python 2, теперь начали выдавать ошибки UnicodeDecodeError и UnicodeEncodeError в Python 3.

    Основное отличие заключается в том, что поведение обработки текста по умолчанию в Python 3 направлено на обнаружение проблем с кодировкой текста как можно раньше — либо при чтении неправильно закодированного текста (обозначается UnicodeDecodeError ), либо при запросе на запись текстовой последовательности, которая не может быть быть правильно представлены в целевой кодировке (обозначается UnicodeEncodeError ).

    Это контрастирует с подходом Python 2, который допускал повреждение данных по умолчанию, а строгие проверки правильности должны были запрашиваться явно. Это, безусловно, могло быть удобным, когда обрабатываемые данные представляли собой преимущественно текст ASCII, а случайное повреждение данных было маловероятным даже для обнаружения, не говоря уже о том, чтобы вызвать проблемы, но вряд ли это прочная основа для создания надежного многоязычные приложения (об этом знает любой, кто когда-либо сталкивался с ошибкой UnicodeError в Python 2).

    Тем не менее, Python 3 предоставляет ряд механизмов для ослабления строгих проверок по умолчанию, чтобы обрабатывать различные варианты использования обработки текста (в частности, случаи использования, когда обработка «наилучших усилий» приемлема, а строгая правильность не требуется). . В этой статье мы попытаемся объяснить некоторые из них, рассмотрев случаи, когда их можно было бы использовать.

    Обратите внимание, что многие функции, которые я обсуждаю ниже, также доступны в Python 2, но вы должны получить к ним явный доступ через тип unicode и модуль codecs. В Python 3 они являются частью поведения типа str и встроенной функции open.

    Основы Юникода¶

    Чтобы эффективно обрабатывать текст в Python 3, необходимо хотя бы немного узнать о Unicode и кодировках текста:

    Обработчики ошибок Unicode¶

    Чтобы помочь стандартизировать различные методы обработки ошибок кодирования и декодирования Unicode, Python включает концепцию обработчиков ошибок Unicode, которые автоматически вызываются при возникновении проблемы в процессе кодирования или декодирования текста.

    Я не буду описывать их все в этой статье, но три из них имеют особое значение:

    • strict : это обработчик ошибок по умолчанию, который просто вызывает UnicodeDecodeError при проблемах с декодированием и UnicodeEncodeError при проблемах с кодированием.
    • surrogateescape : это обработчик ошибок, который Python использует для большинства API-интерфейсов ОС, чтобы изящно справляться с проблемами кодирования в данных, предоставляемых ОС. Он обрабатывает ошибки декодирования, помещая данные в малоиспользуемую часть пространства кодовых точек Unicode (для тех, кто интересуется более подробно, см. PEP 383). При кодировании он переводит эти скрытые значения обратно в точную исходную последовательность байтов, которую не удалось правильно декодировать. Подобно тому, как это полезно для API ОС, это может упростить изящную обработку проблем кодирования в других контекстах.
    • backslashreplace : это обработчик ошибок кодирования, который преобразует кодовые точки, которые не могут быть представлены в целевой кодировке, в эквивалентную числовую escape-последовательность строки Python. Это позволяет легко гарантировать, что UnicodeEncodeError никогда не будет выброшен, но при этом не потеряется много информации (поскольку мы не хотим, чтобы проблемы с кодированием скрывали вывод ошибок, этот обработчик ошибок включен в sys.stderr по умолчанию).

    Бинарный опцион¶

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

    Однако как для «текстовых данных с неизвестной кодировкой», так и для «текстовых данных с известной кодировкой, но потенциально содержащих ошибки кодирования» часто предпочтительнее привести их в форму, которую можно обрабатывать как текстовые строки. В частности, некоторые API, которые принимают как байты, так и текст, могут быть очень строгими в отношении кодирования принимаемых ими байтов (например, модуль urllib.urlparse принимает только чистые данные ASCII для обработки в виде байтов, но с радостью обработает текстовые строки, содержащие не -кодовые точки ASCII).

    Обработка текстовых файлов¶

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

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

    Файлы в кодировке, совместимой с ASCII, допустимы все усилия¶

    Случай использования: обрабатываемые файлы имеют кодировку, совместимую с ASCII, но вы точно не знаете, какую именно. Все файлы должны обрабатываться без каких-либо исключений, но некоторый риск повреждения данных считается приемлемым (например, сопоставление файлов журналов из нескольких источников, где некоторые ошибки данных допустимы, при условии, что журналы остаются в основном неповрежденными) .

    Подход: используйте кодировку "latin-1" для сопоставления значений байтов непосредственно с первыми 256 кодовыми точками Unicode. Это самый близкий эквивалент, который предлагает Python 3 для разрешающей модели обработки текста Python 2.

    Пример: f = open(fname, encoding="latin-1")

    Хотя кодировку Windows cp1252 также иногда называют "latin-1", она не отображает все возможные значения байтов, поэтому ее необходимо использовать в сочетании с обработчиком ошибок surrogateescape, чтобы она никогда не выдавала UnicodeDecodeError . Кодировка latin-1 в Python реализует ISO_8859-1:1987, который сопоставляет все возможные значения байтов с первыми 256 кодовыми точками Unicode и, таким образом, гарантирует, что ошибки декодирования никогда не возникнут независимо от настроенного обработчика ошибок.

    Последствия:

    • данные не будут повреждены, если их просто прочитать, обработать как текст ASCII и снова записать.
    • никогда не вызовет ошибку UnicodeDecodeError при чтении данных
    • все равно вызовет ошибку UnicodeEncodeError, если кодовые точки выше 0xFF (например, умные кавычки, скопированные из программы обработки текстов) добавляются к текстовой строке до того, как она будет закодирована обратно в байты. Чтобы предотвратить такие ошибки, используйте обработчик ошибок с обратной косой чертой (или один из других обработчиков ошибок, который заменяет кодовые точки Unicode без представления в целевой кодировке последовательностями кодовых точек ASCII).
    • может произойти повреждение данных, если исходные данные имеют кодировку, несовместимую с ASCII (например, UTF-16)
    • может произойти повреждение, если данные записываются с использованием кодировки, отличной от latin-1.
    • повреждение может произойти, если элементы строки, отличные от ASCII, будут изменены напрямую (например,для кодировки переменной ширины, такой как UTF-8, которая вместо этого была декодирована как latin-1, разрезание строки в произвольной точке может разделить многобайтовый символ на две части)

    Файлы в кодировке, совместимой с ASCII, минимизируют риск повреждения данных¶

    Случай использования: обрабатываемые файлы имеют кодировку, совместимую с ASCII, но вы точно не знаете, какую именно. Все файлы должны обрабатываться без каких-либо исключений, но некоторые ошибки, связанные с Unicode, допустимы, чтобы снизить риск повреждения данных (например, сопоставление файлов журналов из нескольких источников, но желательно более явное уведомление при сопоставлении). данные могут быть повреждены из-за ошибок программирования, которые нарушают принцип обратной записи данных только в исходной кодировке)

    Подход: используйте кодировку ascii с обработчиком ошибок surrogateescape.

    Пример: f = open(fname, encoding="ascii", errors="surrogateescape")

    Последствия:

    • данные не будут повреждены, если их просто прочитать, обработать как текст ASCII и снова записать.
    • никогда не вызовет ошибку UnicodeDecodeError при чтении данных
    • все равно вызовет ошибку UnicodeEncodeError, если кодовые точки выше 0xFF (например, умные кавычки, скопированные из программы обработки текстов) добавляются к текстовой строке до того, как она будет закодирована обратно в байты. Чтобы предотвратить такие ошибки, используйте обработчик ошибок с обратной косой чертой (или один из других обработчиков ошибок, который заменяет кодовые точки Unicode без представления в целевой кодировке последовательностями кодовых точек ASCII).
    • также вызовет ошибку UnicodeEncodeError, если будет предпринята попытка закодировать текстовую строку, содержащую экранированные значения байтов, без включения обработчика ошибок surrogateescape (или еще более терпимого обработчика, такого как обратная косая черта ).
    • некоторые библиотеки обработки Unicode, обеспечивающие правильность последовательности кодовых точек, могут жаловаться на используемый механизм экранирования (я не буду объяснять, что он здесь означает, но фраза «одиночный суррогат» намекает на то, что что-то из этих линии могут возникать — тот факт, что слово «surrogate» также появляется в имени обработчика ошибок, не является совпадением).
    • повреждение данных все еще может произойти, если исходные данные находятся в кодировке, несовместимой с ASCII (например, UTF-16)
    • повреждение данных также возможно, если экранированные части строки изменяются напрямую

    Файлы в стандартной кодировке для конкретной платформы¶

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

    Подход: просто откройте файл в текстовом режиме. Этот вариант использования описывает поведение по умолчанию в Python 3.

    Пример: f = open(fname)

    Последствия:

    • При чтении таких файлов может возникнуть ошибка UnicodeDecodeError (если данные на самом деле не в кодировке, возвращаемой locale.getpreferredencoding() )
    • При записи таких файлов может возникнуть ошибка UnicodeEncodeError (при попытке записи кодовых точек, которые не представлены в целевой кодировке).
    • обработчик ошибок surrogateescape можно использовать, чтобы быть более терпимым к ошибкам кодирования, если необходимо приложить все усилия для обработки файлов, содержащих такие ошибки, вместо того, чтобы сразу отклонять их как недопустимые входные данные.

    Файлы в согласованной известной кодировке¶

    Случай использования: файлы, которые нужно обработать, номинально имеют согласованную кодировку, вы заранее знаете точную кодировку, и допустимо отказаться от обработки файлов, которые не закодированы должным образом. Это становится все более и более распространенным явлением, особенно с учетом того, что многие форматы текстовых файлов начинают стандартизироваться с использованием UTF-8 в качестве предпочтительной кодировки текста.

    Подход: открыть файл в текстовом режиме с соответствующей кодировкой

    Пример: f = open(fname, encoding="utf-8")

    Последствия:

    • При чтении таких файлов может возникнуть ошибка UnicodeDecodeError (если данные на самом деле не в указанной кодировке)
    • При записи таких файлов может возникнуть ошибка UnicodeEncodeError (при попытке записи кодовых точек, которые не представлены в целевой кодировке).
    • обработчик ошибок surrogateescape можно использовать, чтобы быть более терпимым к ошибкам кодирования, если необходимо приложить все усилия для обработки файлов, содержащих такие ошибки, вместо того, чтобы сразу отклонять их как недопустимые входные данные.

    Файлы с надежным маркером кодировки¶

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

    Подход: сначала откройте файл в двоичном режиме, чтобы найти маркер кодировки, а затем снова откройте в текстовом режиме с идентифицированной кодировкой.

    Пример: f = tokenize.open(fname) использует маркеры кодировки PEP 263 для определения кодировки исходных файлов Python (по умолчанию используется UTF-8, если маркер кодировки не обнаружен)

    Последствия:

    • может работать с файлами в разных кодировках
    • может по-прежнему вызывать ошибку UnicodeDecodeError, если маркер кодировки неверен
    • при записи таких файлов необходимо убедиться, что маркер установлен правильно
    • даже если это не кодировка по умолчанию, для отдельных файлов все же можно настроить использование UTF-8 в качестве кодировки, чтобы поддерживать кодировку почти всех кодовых точек Unicode.
    • обработчик ошибок surrogateescape можно использовать, чтобы быть более терпимым к ошибкам кодирования, если необходимо приложить все усилия для обработки файлов, содержащих такие ошибки, вместо того, чтобы сразу отклонять их как недопустимые входные данные.

    © Copyright 2011, Nick Coghlan, редакция 2fb5e696.

    Версии последние Загрузки pdf html epub On Read the Docs Project Home Сборки Бесплатный хостинг документов, предоставляемый Read the Docs.

    В этом документе объясняется, как Unicode и связанные с ним вопросы обрабатываются в CKAN. Для общего ознакомления с Unicode и обработкой Unicode в Python 2, пожалуйста, прочтите Python 2 Unicode HOWTO. Поскольку обработка Unicode сильно различается между Python 2 и Python 3, вас также может заинтересовать Python 3 Unicode HOWTO.

    CKAN использует модуль six для обеспечения одновременной совместимости с Python 2 и Python 3. В Python 3 все строки имеют кодировку Unicode, поэтому встроенные юникод и базовая строка были удалены, поэтому необходимо соблюдать несколько общих правил:

    1. Заменить все вызовы basestring() на вызовы six.string_types()
    2. Замените оставшиеся экземпляры basestring на six.string_types
    3. Замените все экземпляры (str, unicode) на six.string_types
    4. Заменить все вызовы unicode() на вызовы six.text_type()
    5. Замените оставшиеся экземпляры Unicode на six.text_type

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

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

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

    Общая стратегия¶

    CKAN использует Unicode только для внутреннего использования ( six.text_type как в Python 2, так и в Python 3). При необходимости преобразование в/из строк ASCII происходит на границе с другими системами/библиотеками.

    Кодирование файлов Python¶

    Файлы, содержащие исходный код Python ( *.py ), должны быть закодированы с использованием UTF-8, а кодировка должна быть объявлена ​​с использованием следующего заголовка:

    Эта строка должна быть первой или второй строкой в ​​файле. Подробнее см. в PEP 263.

    Строковые литералы¶

    Строковые литералы — это строковые значения, заданные непосредственно в исходном коде (в отличие от строковых переменных, считанных из файла, полученных через аргумент и т. д.). В Python 2 строковые литералы по умолчанию имеют тип str. Их можно изменить на юникод, добавив префикс u. Кроме того, префикс b может использоваться для явного обозначения литерала как str :

    В Python 3 все str имеют кодировку Unicode, а str и bytes явно относятся к разным типам данных, поэтому:

    В CKAN каждый строковый литерал должен иметь префикс u или b. Хотя последнее в Python 2 является излишним, оно делает намерение разработчика явным и упрощает будущий переход на Python 3.

    Это правило также применимо к необработанным строкам, созданным с использованием префикса r. Просто используйте вместо этого ur:

    Дополнительную информацию о строковых префиксах см. в документации по Python.

    Оператор будущего unicode_literals не используется в CKAN.

    Рекомендации¶

    Используйте io.open для открытия текстовых файлов¶

    При открытии текстовых (не двоичных) файлов следует использовать io.open вместо open . Это позволяет указать кодировку файла, а операции чтения будут возвращать Unicode вместо ASCII:

    Текстовые файлы должны быть закодированы с использованием UTF-8, если это возможно.

    Нормализация строк перед их сравнением¶

    Для многих символов Unicode предлагает несколько описаний. Например, маленькую латинскую букву e с острым ударением (é) можно указать либо с помощью специальной кодовой точки (U+00E9), либо путем комбинации кодовых точек для e (U+0065) и ударения (U+0301). Оба варианта будут выглядеть одинаково, но будут отличаться с числовой точки зрения:

    Поэтому, если вы хотите сравнить две строки Unicode на основе их символов, вам нужно сначала нормализовать их, используя unicodedata.normalize:

    Использовать флаг Unicode в регулярных выражениях¶

    По умолчанию классы символов модуля Python re ( \w , \d , …) соответствуют только символам ASCII. Например, \w (буквенно-цифровой символ) по умолчанию не соответствует ö :

    Поэтому вам необходимо явно активировать режим Unicode, передав флаг re.U:

    Некоторые функции (например, re.split и re.sub ) принимают дополнительные необязательные параметры перед флагами, поэтому вы должны передать флаг через аргумент ключевого слова:

    Тип значений, возвращаемых re.split , re.MatchObject.group и т. д., зависит от типа входной строки:

    Обратите внимание, что тип строки шаблона не влияет на тип возвращаемого значения.

    Имена файлов¶

    Как и все другие строки, имена файлов должны храниться внутри как строки Unicode. Однако некоторые операции с файловой системой возвращают или ожидают байтовые строки, поэтому имена файлов должны быть закодированы/декодированы соответствующим образом. К сожалению, разные операционные системы используют разные кодировки для имен файлов, а в некоторых из них (например, в Linux) пользователь даже может настроить кодировку файловой системы.

    Чтобы облегчить декодирование и кодирование имен файлов, модуль ckan.lib.io содержит функции decode_path и encode_path , которые автоматически используют правильную кодировку:

    Обратите внимание, что почти все встроенные функции ввода-вывода Python принимают имена файлов в формате Unicode в качестве входных данных и автоматически кодируют их, поэтому использование encode_path обычно не требуется.

    Тип возвращаемого значения некоторых функций ввода-вывода Python (например, os.listdir и os.walk) зависит от типа их входных данных: если переданы байтовые строки, они возвращают байтовые строки, а если переданы Unicode, они автоматически декодируют необработанные данные. имена файлов в Unicode перед их возвратом. Другие функции существуют в двух вариантах, которые возвращают строки байтов (например, os.getcwd) и Unicode (os.getcwdu) соответственно.

    Некоторые функции ввода-вывода Python могут возвращать как байтовые строки, так и строки Unicode для одного вызова. Например, os.listdir обычно возвращает Unicode при передаче Unicode, но имена файлов, которые не могут быть декодированы с использованием кодировки файловой системы, все равно будут возвращены в виде байтовых строк!

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

    Приведенные выше инструкции предназначены для имен существующих файлов, полученных с помощью функций ввода-вывода Python. Однако иногда также требуется создавать новые файлы, имена которых генерируются из неизвестных источников (например, пользовательский ввод). Чтобы убедиться, что сгенерированное имя файла безопасно для использования и может быть представлено с использованием кодировки файловой системы, используйте ckan.lib.munge.munge_filename :

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

    Правда в том, что даже такая простая вещь, как текст, требует хорошо скоординированной, четко определенной системы для отображения в веб-браузерах. В этом посте я объясню основы одной технологии, центральной для текста в Интернете, UTF-8. Мы изучим основы хранения и кодирования текста и обсудим, как это помогает размещать привлекательные слова на вашем сайте.

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

    Что такое UTF-8?

    UTF-8 расшифровывается как «Формат преобразования Unicode — 8 бит». Нам это пока не поможет, поэтому давайте вернемся к основам.

    Двоичный файл: как компьютеры хранят информацию

    Для хранения информации компьютеры используют двоичную систему. В двоичном формате все данные представлены в виде последовательностей 1 и 0. Основной единицей двоичного кода является бит, представляющий собой одну единицу или 0. Следующая по величине единица двоичного кода, байт, состоит из 8 бит. Пример байта: «01101011».

    Каждый цифровой объект, с которым вы когда-либо сталкивались, — от программного обеспечения до мобильных приложений, веб-сайтов и историй в Instagram — построен на этой системе байтов, которые связаны друг с другом таким образом, который имеет смысл для компьютеров. Когда мы говорим о размерах файлов, мы имеем в виду количество байтов. Например, килобайт — это примерно тысяча байтов, а гигабайт — примерно миллиард байтов.

    Текст — это один из многих ресурсов, которые хранятся и обрабатываются компьютерами. Текст состоит из отдельных символов, каждый из которых представлен в компьютере строкой битов. Эти строки объединяются в цифровые слова, предложения, абзацы, любовные романы и т. д.

    ASCII: преобразование символов в двоичные

    Американский стандартный код для обмена информацией (ASCII) был ранней стандартизированной системой кодирования текста. Кодирование — это процесс преобразования символов человеческого языка в двоичные последовательности, которые могут обрабатываться компьютером.

    Библиотека ASCII включает все прописные и строчные буквы латинского алфавита (A, B, C...), все цифры от 0 до 9 и некоторые распространенные символы (такие как /, ! и ?). Каждому из этих символов присваивается уникальный трехзначный код и уникальный байт.

    В таблице ниже показаны примеры символов ASCII с соответствующими кодами и байтами.

    Точно так же, как символы объединяются в слова и предложения в языке, двоичный код делает то же самое в текстовых файлах. Итак, предложение «Быстрая коричневая лиса перепрыгивает через ленивую собаку». представленный в двоичном формате ASCII, будет:

    Это мало что значит для нас, людей, но для компьютера это хлеб с маслом.

    Количество символов, которые может представлять ASCII, ограничено количеством доступных уникальных байтов, поскольку каждый символ получает один байт. Если вы посчитаете, то обнаружите, что существует 256 различных способов сгруппировать восемь единиц и нулей вместе. Это дает нам 256 различных байтов или 256 способов представления символа в ASCII. Когда в 1960 году была введена ASCII, это было нормально, поскольку разработчикам требовалось всего 128 байт для представления всех нужных им английских букв и символов.

    Но по мере глобального распространения вычислительной техники компьютерные системы стали хранить текст на других языках, помимо английского, многие из которых использовали символы, отличные от ASCII. Были созданы новые системы для сопоставления других языков с одним и тем же набором из 256 уникальных байтов, но наличие нескольких систем кодирования было неэффективным и запутанным. Разработчикам требовался лучший способ кодирования всех возможных символов в одной системе.

    Юникод: способ хранения всех символов

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

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

    Ниже приведены некоторые примеры текстовых символов и соответствующие им кодовые точки. Каждая кодовая точка начинается с «U» для «Unicode», за которой следует уникальная строка символов для представления символа.

    Если вы хотите узнать, как генерируются кодовые точки и что они означают в Unicode, ознакомьтесь с этим подробным объяснением.

    Итак, теперь у нас есть стандартизированный способ представления каждого символа, используемого каждым человеческим языком, в одной библиотеке. Это решает проблему множественных систем маркировки для разных языков — любой компьютер на Земле может использовать Unicode.

    Однако Unicode сам по себе не хранит слова в двоичном формате. Компьютерам нужен способ перевода Unicode в двоичный код, чтобы его символы можно было хранить в текстовых файлах. Здесь на помощь приходит кодировка UTF-8.

    UTF-8: последняя часть головоломки

    UTF-8 – это система кодирования Unicode. Он может преобразовать любой символ Unicode в соответствующую уникальную двоичную строку, а также может преобразовать двоичную строку обратно в символ Unicode. В этом смысл «UTF» или «формата преобразования Unicode».

    Помимо UTF-8, для Unicode существуют и другие системы кодирования, но UTF-8 уникальна, поскольку представляет символы в однобайтовых блоках. Помните, что один байт состоит из восьми битов, отсюда и «-8» в его имени.

    В частности, UTF-8 преобразует кодовую точку (которая представляет один символ в Unicode) в набор от одного до четырех байтов. Первые 256 символов в библиотеке Unicode, включая символы, которые мы видели в ASCII, представлены как один байт. Символы, которые появляются позже в библиотеке Unicode, кодируются как двухбайтовые, трехбайтовые и, возможно, четырехбайтовые двоичные единицы.

    Ниже приведена та же таблица символов, что и выше, с выводом UTF-8 для каждого добавленного символа. Обратите внимание, что некоторые символы представлены одним байтом, в то время как другие используют больше.

    Почему UTF-8 преобразовывает одни символы в один байт, а другие — в четыре байта? Короче, для экономии памяти. Используя меньше места для представления более распространенных символов (например, символов ASCII), UTF-8 уменьшает размер файла, позволяя использовать гораздо большее количество менее распространенных символов. Эти менее распространенные символы закодированы в два или более байта, но это нормально, если они хранятся экономно.

    Пространственная эффективность — ключевое преимущество кодировки UTF-8. Если бы вместо этого каждый символ Unicode был представлен четырьмя байтами, текстовый файл, написанный на английском языке, был бы в четыре раза больше по размеру того же файла, закодированного с помощью UTF-8.

    Еще одним преимуществом кодировки UTF-8 является ее обратная совместимость с ASCII. Первые 128 символов в библиотеке Unicode совпадают с символами в библиотеке ASCII, и UTF-8 переводит эти 128 символов Unicode в те же двоичные строки, что и ASCII. В результате UTF-8 может без проблем преобразовать текстовый файл, отформатированный в ASCII, в удобочитаемый текст.

    Символы UTF-8 в веб-разработке

    UTF-8 – это наиболее распространенный метод кодировки символов, используемый сегодня в Интернете, а также набор символов по умолчанию для HTML5. Более 95% всех веб-сайтов, включая ваш собственный, хранят символы таким образом. Кроме того, распространенные методы передачи данных через Интернет, такие как XML и JSON, кодируются в соответствии со стандартами UTF-8.

    Поскольку теперь это стандартный метод кодирования текста в Интернете, все страницы вашего сайта и базы данных должны использовать кодировку UTF-8. Система управления контентом или конструктор веб-сайтов по умолчанию сохраняют ваши файлы в формате UTF-8, но все же рекомендуется убедиться, что вы придерживаетесь этой рекомендации.

    Текстовые файлы, закодированные с помощью UTF-8, должны указывать это программному обеспечению, которое их обрабатывает. В противном случае программное обеспечение не сможет правильно преобразовать двоичный файл обратно в символы. В файлах HTML вы можете увидеть строку кода, подобную следующей, вверху:

    Это сообщает браузеру, что HTML-файл закодирован в UTF-8, чтобы браузер мог преобразовать его обратно в разборчивый текст.

    UTF-8 и UTF-16

    Как я уже упоминал, UTF-8 — не единственный метод кодирования символов Unicode. Существует также UTF-16. Эти методы различаются количеством байтов, необходимых для хранения символа. UTF-8 кодирует символ в двоичную строку из одного, двух, трех или четырех байтов. UTF-16 кодирует символ Юникода в строку из двух или четырех байтов.

    Это различие очевидно из их имен. В UTF-8 наименьшее двоичное представление символа составляет один байт или восемь бит. В UTF-16 наименьшее двоичное представление символа составляет два байта или шестнадцать бит.

    И UTF-8, и UTF-16 могут преобразовывать символы Unicode в двоичные файлы, удобные для компьютера, и обратно. Однако они не совместимы друг с другом. Эти системы используют разные алгоритмы для преобразования кодовых точек в двоичные строки, поэтому двоичный вывод для любого заданного символа будет выглядеть по-разному при использовании обоих методов:

    Кодировка UTF-8 предпочтительнее UTF-16 на большинстве веб-сайтов, поскольку она использует меньше памяти. Напомним, что UTF-8 кодирует каждый символ ASCII всего одним байтом. UTF-16 должен кодировать эти же символы двумя или четырьмя байтами. Это означает, что текстовый файл на английском языке, закодированный с помощью UTF-16, будет как минимум вдвое больше, чем тот же файл, закодированный с помощью UTF-8.

    UTF-16 эффективнее, чем UTF-8, только на некоторых веб-сайтах, отличных от английского. Если веб-сайт использует язык с более ранними символами в библиотеке Unicode, UTF-8 будет кодировать все символы как четыре байта, тогда как UTF-16 может кодировать многие из тех же символов только как два байта. Тем не менее, если ваши страницы заполнены буквами ABC и 123, придерживайтесь UTF-8.

    Расшифровка мира кодировки UTF-8

    Это было много слов о словах, так что давайте подытожим то, что мы рассмотрели:

    1. Компьютеры хранят данные, включая текстовые символы, в двоичном формате (1 и 0).
    2. ASCII был одним из первых способов кодирования или преобразования символов в двоичный код, чтобы компьютеры могли их хранить. Однако в ASCII недостаточно места для представления нелатинских символов и чисел в двоичном формате.
    3. Решением этой проблемы стал Unicode. Unicode присваивает уникальный «код» каждому символу в любом человеческом языке.
    4. UTF-8 — это метод кодировки символов Unicode. Это означает, что UTF-8 берет кодовую точку для данного символа Unicode и переводит ее в двоичную строку. Он также делает обратное, читая двоичные цифры и преобразовывая их обратно в символы.
    5. В настоящее время UTF-8 является самым популярным методом кодирования в Интернете, поскольку он может эффективно хранить текст, содержащий любой символ.
    6. UTF-16 — это еще один метод кодирования, но он менее эффективен для хранения текстовых файлов (за исключением тех, которые написаны на некоторых языках, отличных от английского).

    Перевод Unicode — это не то, о чем большинству из нас нужно думать при просмотре или разработке веб-сайтов, и именно в этом суть — создать единую систему обработки текста, которая работает для всех языков и веб-браузеров. Если он работает хорошо, вы этого не заметите.

    Но если вы обнаружите, что страницы вашего веб-сайта занимают слишком много места или если ваш текст замусорен символами ▢s и �s, пришло время применить ваши новые знания UTF-8 на практике.

    Я пишу скрипт, который попытается кодировать байты во множество различных кодировок в Python 2.6. Есть ли способ получить список доступных кодировок, которые я могу перебирать?

    Причина, по которой я пытаюсь это сделать, заключается в том, что у пользователя есть некоторый текст, который закодирован неправильно. Есть забавные персонажи. Я знаю символ Юникода, который все портит. Я хочу иметь возможность дать им ответ типа «Ваш текстовый редактор интерпретирует эту строку как кодировку X, а не кодировку Y». Я подумал, что попробую закодировать этот символ, используя одну кодировку, затем снова декодировать его, используя другую кодировку, и посмотреть, получим ли мы ту же последовательность символов.

    т.е. что-то вроде этого:

    Возможно, вам следует начать новый вопрос, подробно описав, в чем заключается реальная проблема, в том числе откуда вы знаете, какой символ Unicode мешает, и что означает "неправильно" и что такое "забавные символы" are и т. д. и т. д. Если оскорбительные данные находятся в файле, покажите соответствующую часть вывода print repr(open('thefile.txt', 'rb').читать())

    Эта функциональность мне понадобилась при очистке больших файловых ресурсов от имен файлов, отличных от UTF. Неизвестно, какая была исходная кодировка для многих файлов. Некоторые из этих встроенных «нечетных» одиночных байтов не соответствовали ни одной кодовой точке в Windows-1252 или ISO-8859, и полезным способом угадать, из какого набора они произошли, было заставить Python преобразовать одиночный байт в каждую кодировку, которую он может использовать. , и посмотрите, был ли результат разумным. Затем исправьте имя файла.

    Я реализовал скрипт, который использует идеи Анурага Унияла и u0b34a0f6ae для получения списка доступных кодеков. Скрипт также тестирует кодеки для всех значений байтов и измеряет производительность.

    10 ответов 10

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

    Вы можете найти эти списки (для каждой выпущенной стабильной версии языка) по адресу:

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

    Python 2.3 (59 кодировок)

    Python 2.4 (85 кодировок)

    Python 2.5 (86 кодировок)

    Python 2.6 (90 кодировок)

    Python 2.7 (93 кодировки)

    Python 3.0 (89 кодировок)

    Python 3.1 (90 кодировок)

    Python 3.2 (92 кодировки)

    Python 3.3 (93 кодировки)

    Python 3.4 (96 кодировок)

    Python 3.5 (98 кодировок)

    Python 3.6 (98 кодировок)

    Python 3.7 (98 кодировок)

    В случае, если они имеют отношение к чьему-либо варианту использования, обратите внимание, что в документации также перечислены некоторые специфичные для Python кодировки, многие из которых, по-видимому, в основном предназначены для использования внутренними компонентами Python или иным образом странны, например, «неопределенный ' кодировка, которая всегда выдает исключение, если вы пытаетесь ее использовать. Вы, вероятно, захотите полностью их игнорировать, если, подобно тому, кто задает вопрос здесь, вы пытаетесь выяснить, какая кодировка использовалась для некоторого текста, с которым вы столкнулись в реальном мире. Начиная с Python 3.7, список выглядит следующим образом:

    В некоторых старых версиях Python была специальная кодировка string_escape, которую я не включил в приведенный выше список, поскольку она была удалена из языка.

    Наконец, если вы хотите обновить мои таблицы выше для более новой версии Python, вот (грубый, не очень надежный) скрипт, который я использовал для их создания:

    @VictorSchröder Не так. Быстрый поиск в Google показывает, что cp037 и IBM037 являются псевдонимами, а cp037 есть в списке.

    Спасибо, @Mark Amery, действительно, я нашел ту же информацию примерно через минуту после моего претенциозно смешного комментария выше. К сожалению, кодировка EBCDIC имеет свои особенности, и простое декодирование не работает должным образом, чтобы иметь действительный эквивалент UTF-8. Он оставляет несколько непечатаемых символов позади. Конечно, это не вина Python, но было бы неплохо иметь дампы БД, как будто мы уже пережили 1992 год.

    К сожалению, encodings.aliases.aliases.keys() НЕ является подходящим ответом.

    псевдонимы (как и следовало ожидать) содержат несколько случаев, когда разные ключи сопоставляются с одним и тем же значением, например. 1252 и windows_1252 сопоставляются с cp1252. Вы можете сэкономить время, если вместо aliases.keys() использовать set(aliases.values()) .

    НО ЕСТЬ ПРОБЛЕМА ХУЖЕ: псевдонимы не содержат кодеков, у которых нет псевдонимов (например, cp856, cp874, cp875, cp737 и koi8_u).

    Также стоит отметить, что, как бы вы ни получали полный список кодеков, может быть хорошей идеей игнорировать кодеки, которые не связаны с наборами символов кодирования/декодирования, а выполняют некоторые другие преобразования, например. zlib , quopri и base64 .

    Что подводит нас к вопросу, ПОЧЕМУ вы хотите "попробовать кодировать байты во множество разных кодировок". Если мы это узнаем, возможно, мы сможем направить вас в правильном направлении.

    Для начала, это неоднозначно. Один декодирует байты в юникод, а другой кодирует юникод в байты. Что вы хотите сделать?

    Чего вы на самом деле пытаетесь достичь: вы пытаетесь определить, какой кодек использовать для декодирования некоторых входящих байтов, и планируете попытаться сделать это со всеми возможными кодеками? [примечание: latin1 декодирует что угодно] Вы пытаетесь определить язык какого-либо текста Unicode, пытаясь закодировать его всеми возможными кодеками? [примечание: utf8 будет кодировать что угодно].

    Читайте также: