Python UnicodeDecodeError - Я неправильно понимаю кодирование? - PullRequest
54 голосов
/ 15 декабря 2008

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

>>> '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)

Ответы [ 3 ]

210 голосов
/ 16 декабря 2008

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

Небольшая преамбула: думайте о юникоде как о норме или идеальном состоянии. Юникод - это просто таблица символов. №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; древние римляне, древние греки, древние египтяне не слишком. Все они имели свои собственные «кодировки» и почти не уважали другие культуры. Все эти цивилизации рассыпались в прах. Думайте об этом люди! Сделайте свои приложения Unicode-осведомленными, на благо человечества. :)

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

4 голосов
/ 15 декабря 2008

кодирование доступно для строк Unicode, но у вас есть строка, которая не выглядит как Unicode (попробуйте с u'add \ x93Monitoring \ x93 to list ')

>>> u'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
'add \x93Monitoring\x93 to list '
0 голосов
/ 15 декабря 2008

Это похоже на работу:

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

Есть проблемы с этим? Интересно, когда появятся слова «игнорировать», «заменить» и другие подобные ошибки кодирования?

...