Метод str.encode() в Python
Метод encode() строки возвращает закодированную версию данной строки.
Начиная с Python 3.0, строки хранятся как Unicode, т.е. каждый символ в строке представлен кодовой точкой. Итак, каждая строка ‒ это просто последовательность кодовых точек Unicode.
Для эффективного хранения этих строк последовательность кодовых точек преобразуется в набор байтов. Этот процесс известен как кодирование.
Существуют различные кодировки, которые по-разному обрабатывают строку. Популярные кодировки: utf-8, ascii и т. Д.
Используя строковый метод encode(), вы можете преобразовывать не кодированные строки в любые кодировки, поддерживаемые Python. По умолчанию Python использует кодировку utf-8.
string.encode(encoding='UTF-8',errors='strict')
Параметры
По умолчанию метод не требует никаких параметров. Он возвращает версию строки в кодировке utf-8. В случае сбоя возникает исключение UnicodeDecodeError.
Однако он принимает два параметра:
- кодировка ‒ тип кодировки, в который должна быть закодирована строка;
- ошибки ‒ ответ при сбое кодирования. Есть шесть типов реакции на ошибку:
- strict ‒ ответ по умолчанию, который вызывает исключение UnicodeDecodeError при сбое;
- ignore ‒ игнорирует некодируемый юникод из результата;
- replace ‒ заменяет некодируемый юникод на вопросительный знак;
- xmlcharrefreplace ‒ вставляет ссылку на символ XML вместо некодируемого юникода;
- backslashreplace ‒ вставляет escape-последовательность\uNNNN вместо некодируемого юникода;
- namereplace ‒ вставляет escape-последовательность\N вместо некодируемого юникода.
Пример 1: Кодирование в кодировку Utf-8 по умолчанию
# unicode string string = 'pythön!' # print string print('The string is:', string) # default encoding to utf-8 string_utf = string.encode() # print result print('The encoded version is:', string_utf)
The string is: pythön! The encoded version is: b'pyth\xc3\xb6n!'
Пример 2: Кодирование с параметром ошибки
# unicode string string = 'pythön!' # print string print('The string is:', string) # ignore error print('The encoded version (with ignore) is:', string.encode("ascii", "ignore")) # replace error print('The encoded version (with replace) is:', string.encode("ascii", "replace"))
The string is: pythön! The encoded version (with ignore) is: b'pythn!' The encoded version (with replace) is: b'pyth?n!'
Примечание: Попробуйте также другие параметры кодировки и ошибки.
Ошибки при конвертации#
При конвертации между строками и байтами очень важно точно знать, какая кодировка используется, а также знать о возможностях разных кодировок.
Например, кодировка ASCII не может преобразовать в байты кириллицу:
In [32]: hi_unicode = 'привет' In [33]: hi_unicode.encode('ascii') --------------------------------------------------------------------------- UnicodeEncodeError Traceback (most recent call last) ipython-input-33-ec69c9fd2dae> in module>() ----> 1 hi_unicode.encode('ascii') UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
Аналогично, если строка «привет» преобразована в байты, и попробовать преобразовать ее в строку с помощью ascii, тоже получим ошибку:
In [34]: hi_unicode = 'привет' In [35]: hi_bytes = hi_unicode.encode('utf-8') In [36]: hi_bytes.decode('ascii') --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) ipython-input-36-aa0ada5e44e9> in module>() ----> 1 hi_bytes.decode('ascii') UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Еще один вариант ошибки, когда используются разные кодировки для преобразований:
In [37]: de_hi_unicode = 'grüezi' In [38]: utf_16 = de_hi_unicode.encode('utf-16') In [39]: utf_16.decode('utf-8') --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) ipython-input-39-4b4c731e69e4> in module>() ----> 1 utf_16.decode('utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Наличие ошибок — это хорошо. Они явно говорят, в чем проблема. Хуже, когда получается так:
In [40]: hi_unicode = 'привет' In [41]: hi_bytes = hi_unicode.encode('utf-8') In [42]: hi_bytes Out[42]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [43]: hi_bytes.decode('utf-16') Out[43]: '뿐胑룐닐뗐苑'
Обработка ошибок#
У методов encode и decode есть режимы обработки ошибок, которые указывают, как реагировать на ошибку преобразования.
Параметр errors в encode#
По умолчанию encode использует режим strict — при возникновении ошибок кодировки генерируется исключение UnicodeError. Примеры такого поведения были выше.
Вместо этого режима можно использовать replace, чтобы заменить символ знаком вопроса:
In [44]: de_hi_unicode = 'grüezi' In [45]: de_hi_unicode.encode('ascii', 'replace') Out[45]: b'gr?ezi'
Или namereplace, чтобы заменить символ именем:
In [46]: de_hi_unicode = 'grüezi' In [47]: de_hi_unicode.encode('ascii', 'namereplace') Out[47]: b'gr\\Nezi'
Кроме того, можно полностью игнорировать символы, которые нельзя закодировать:
In [48]: de_hi_unicode = 'grüezi' In [49]: de_hi_unicode.encode('ascii', 'ignore') Out[49]: b'grezi'
Параметр errors в decode#
В методе decode по умолчанию тоже используется режим strict и генерируется исключение UnicodeDecodeError.
Если изменить режим на ignore, как и в encode, символы будут просто игнорироваться:
In [50]: de_hi_unicode = 'grüezi' In [51]: de_hi_utf8 = de_hi_unicode.encode('utf-8') In [52]: de_hi_utf8 Out[52]: b'gr\xc3\xbcezi' In [53]: de_hi_utf8.decode('ascii', 'ignore') Out[53]: 'grezi'
Режим replace заменит символы:
In [54]: de_hi_unicode = 'grüezi' In [55]: de_hi_utf8 = de_hi_unicode.encode('utf-8') In [56]: de_hi_utf8.decode('ascii', 'replace') Out[56]: 'gr��ezi'