ascii | Старая добрая семибитная кодировка ASCII |
utf-8 | Восьмибитная кодировка переменной длины, самый предпочтительный вариант в большинстве случаев |
latin-1 | Также известна как ISO 8859-1 |
cp-1252 | Стандартная кодировка Windows |
unicode-escape | Буквенный формат Python Unicode, выглядит как \uxxxx или \Uxxxxxxxx |
С помощью кодировки UTF-8 вы можете закодировать все что угодно. Присвоим строку Unicode '\u2603' переменной snowman:
>>> snowman = '\u2603'
snowman — это строка Python Unicode, содержащая один символ независимо от того, сколько байтов может потребоваться для того, чтобы сохранить ее:
>>> len(snowman)
1
Теперь закодируем этот символ последовательностью байтов:
>>> ds = snowman.encode('utf-8')
Как я упоминал ранее, кодировка UTF-8 имеет переменную длину. В этом случае было использовано три байта для того, чтобы закодировать один символ snowman:
>>> len(ds)
3
>>> ds
b'\xe2\x98\x83'
Функция len() возвращает число байтов (3), поскольку ds является переменной bytes.
Вы можете использовать другие кодировки, не только UTF-8, но будете получать ошибки, если строка Unicode не сможет быть обработана другой кодировкой. Например, если вы используете кодировку ascii, у вас ничего не выйдет, если только вы не предоставите строку, состоящую из корректных символов ASCII:
>>> ds = snowman.encode('ascii')
Traceback (most recent call last):
··File "
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603'
in position 0: ordinal not in range(128)
Функция encode() принимает второй аргумент, который помогает вам избежать возникновения исключений, связанных с кодировкой. Его значение по умолчанию, как вы можете увидеть в предыдущем примере, равно 'strict'; при таком значении наблюдается исключение UnicodeEncodeError, если встречается символ, не входящий в кодировку ASCII. Существуют и другие кодировки. Используйте значение 'ignore', чтобы опустить все, что не может быть закодировано:
>>> snowman.encode('ascii', 'ignore')
b''
Используйте значение 'replace', чтобы заменить неизвестные символы символами?:
>>> snowman.encode('ascii', 'replace')
b'?'
Используйте значение 'backslashreplace', чтобы создать строку, содержащую символы Python Unicode вроде unicode-escape:
>>> snowman.encode('ascii', 'backslashreplace')
b'\\u2603'
Вы можете использовать этот вариант, если вам нужна печатаемая версия управляющей последовательности Unicode.
В следующем примере создаются строки символьных сущностей, которые вы можете встретить на веб-страницах:
>>> snowman.encode('ascii', 'xmlcharrefreplace')
b'☃'
Мы декодируем байтовые строки в строки Unicode. Когда мы получаем текст из какого-то внешнего источника (файлы, базы данных, сайты, сетевые API и т. д.), он закодирован в виде байтовой строки. Идея заключается в том, чтобы знать, какая кодировка была использована, чтобы мы могли ее декодировать и получить строку Unicode.
Проблема в следующем: никакая часть байтовой строки не говорит нам о том, какая была использована кодировка. Я уже упоминал опасности копирования/вставки с сайтов. Вы, возможно, посещали сайты, содержащие странные символы в том месте, где должны быть простые символы ASCII.
Создадим строку Unicode, которая называется place и имеет значение 'café':
>>> place = 'caf\u00e9'
>>> place
'café'
>>> type(place)
Закодируем ее в формат UTF-8 с помощью переменной bytes, которая называется place_bytes:
>>> place_bytes = place.encode('utf-8')
>>> place_bytes
b'caf\xc3\xa9'
>>> type(place_bytes)
Обратите внимание на то, что переменная place_bytes содержит пять байтов. Первые три похожи на ASCII (преимущество UTF-8), а последние два кодируют символ «é». Теперь декодируем эту байтовую строку обратно в строку Unicode:
>>> place2 = place_bytes.decode('utf-8')
>>> place2
'café'
Это сработало, поскольку мы закодировали и декодировали строку с помощью кодировки UTF-8. Что, если бы мы указали декодировать ее с помощью какой-нибудь другой кодировки?
>>> place3 = place_bytes.decode('ascii')
Traceback (most recent call last):