Python UnicodeDecodeError - Я неправильно понимаю кодировку?

Любые мысли о том, почему это не работает? Я действительно думал, что "игнорировать" будет правильным.

>>> 'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 4: ordinal not in range(128)

Ответ 1

... есть причина, по которой они называются "кодировками"...

Небольшая преамбула: подумайте о unicode как о норме или о идеальном состоянии. Unicode - это всего лишь таблица символов. №65 - латинский капитал А. №937 - греческая столица омега. Только это.

Чтобы компьютер мог хранить и/или манипулировать Unicode, он должен закодировать его в байтах. Наиболее простой кодировкой Unicode является UCS-4; каждый символ занимает 4 байта, и все ~ 1000000 символов доступны. 4 байта содержат номер символа в таблицах Unicode как 4-байтовое целое число. Еще одна очень полезная кодировка - UTF-8, которая может кодировать любой символ Unicode с одним-четырьмя байтами. Но также есть некоторые ограниченные кодировки, такие как "latin1", которые включают очень ограниченный набор символов, в основном используемых западными странами. Такие кодировки используют только один байт на символ.

В принципе, Unicode может кодироваться многими кодировками, а закодированные строки могут быть декодированы в Unicode. Дело в том, что Unicode пришел довольно поздно, поэтому все мы, выросшие с использованием 8-битного набора символов, узнали слишком поздно, что все это время мы работали с закодированными строками. Кодировка может быть ISO8859-1, или Windows CP437, или CP850, или, или, или, в зависимости от нашей системы по умолчанию.

Итак, когда в исходном коде вы вводите строку "добавить" "Мониторинг" в список "(и, я думаю, вы хотели, чтобы строка" добавила "Мониторинг" в список ", обратите внимание на вторую цитату), вы фактически используете строка, уже закодированная в соответствии с вашей системной кодовой страницей по умолчанию (по байту \x93 Предполагаю, что вы используете кодовую страницу Windows 1252," Western "). Если вы хотите получить Unicode от этого, вам нужно декодировать строку из кодировки" cp1252".

Итак, что вы хотели сделать, было:

"add \x93Monitoring\x94 to list".decode("cp1252", "ignore")

Несчастливо, что Python 2.x также включает метод .encode для строк; это удобная функция для "специальных" кодировок, таких как "zip" или "rot13" или "base64", которые не имеют ничего общего с Unicode.

В любом случае, все, что вам нужно запомнить для конвертирования Unicode в очередь, это:

  • строка Unicode получает кодировку в строку Python 2.x(фактически, последовательность байтов)
  • строка Python 2.x декодируется в строку Unicode

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

Я не очень ясен, я сон, но я надеюсь, что помогу.

PS Юмористическая сторона примечания: у майя не было Юникода; древних римлян, древних греков, древних египтян тоже не было. У всех у них были свои "кодировки" и почти не было уважения к другим культурам. Все эти цивилизации рухнули в пыль. Подумайте об этом люди! Сделайте ваши приложения Unicode-осведомленными, на благо человечества.:)

PS2 Пожалуйста, не испортите предыдущее сообщение, сказав "Но китайцы...". Если вы считаете, что склонны или обязаны это делать, задерживайте это, думая, что BMP Юникода заполняется в основном китайскими идеограммами, эрго китайцы являются основой Юникода. Я могу изобрести возмутительную ложь, пока люди разрабатывают приложения, поддерживающие Unicode. Ура!

Ответ 2

encode доступен для строк unicode, но строка, которую вы там там, не выглядит unicode (попробуйте с u'add\x93Monitoring\x93 для списка)

>>> u'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
'add \x93Monitoring\x93 to list '

Ответ 4

Это работает:

'add \x93Monitoring\x93 to list '.decode('latin-1').encode('latin-1')

Любые проблемы с этим? Интересно, когда "игнорировать", "заменять" и другое подобное кодирование ошибок происходит?