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

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

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

5 ответов


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

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

для того, чтобы компьютер мог хранить и-или манипулировать Unicode, он должен кодирование в байты. Самый простой кодирование Юникода UCS-4; каждый символ занимает 4 байта, и все ~1000000 символы доступны. В 4 байта содержат номер символа в таблице Unicode как 4-байтовое целое число. Еще одна очень полезная кодировка-UTF-8, которая может кодировать любой символ Юникода с одним-четырьмя байтами. Но есть и некоторые ограниченные кодировки, такие как" 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.х включает в себя .encode метод строки тоже; это функция удобства для" специальных "кодировок, таких как" zip "или" rot13 "или" base64", которые не имеют ничего общего с Unicode.

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

  • строка Unicode получает закодированных на Python 2.X строка (на самом деле, это последовательность байт)
  • питон 2.х строки декодируются в строку Unicode

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

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

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

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


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

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

Я также написал длинный блог на эту тему:

хлопот Unicode и получить с ним


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

 genesis_block = {
    'hash': hash_function({
        'block_number': 0,
        'parent_hash': None,
        'transaction_count': 1,
        'transaction': [{'Tom': 10}]
    }),
    'contents': {
        'block_number': 0,
        'parent_hash': None,
        'transaction_count': 1,
        'transaction': [{'Tom': 10}]
    },
}

block_chain = [genesis_block]
chain_state = {'Tom': 10}

Это, кажется, работает:

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

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