Python-кодек 'ascii' не может декодировать байт
Я совсем запуталась. Я попытался закодировать, но ошибка сказала can't decode....
>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
Я знаю, как избежать ошибки с префиксом "u" в строке. Мне просто интересно, почему ошибка "не может декодировать", когда encode был вызван. Что питон делает под капотом?
7 ответов:
"你好".encode('utf-8')
encodeпреобразует объект unicode вstring"объект". Но здесь вы вызвали его наstringобъект (потому что у вас нет u). Поэтому python должен преобразоватьstringдоunicodeобъект первый. Так что он делает эквивалент"你好".decode().encode('utf-8')но декодировать не удается, потому что строка не является допустимым ascii. Вот почему вы получаете жалобу на то, что не можете декодировать.
всегда кодирование из юникода в байтах.
В этом направлении, вы можете выбрать кодировку.>>> u"你好".encode("utf8") '\xe4\xbd\xa0\xe5\xa5\xbd' >>> print _ 你好другой способ-декодировать из байтов в Юникод.
В этом направлении, вы должны знать, что кодировка-это.>>> bytes = '\xe4\xbd\xa0\xe5\xa5\xbd' >>> print bytes 你好 >>> bytes.decode('utf-8') u'\u4f60\u597d' >>> print _ 你好этот пункт не может быть подчеркнуто достаточно. Если вы хотите избежать воспроизведения unicode "whack-a-mole", важно понять, что происходит на уровне данных. Здесь это объясняется по-другому:
- объект unicode уже декодирован, вы никогда не хотите вызывать
decodeна нем.- объект bytestring уже закодирован, вы никогда не хотите вызывать
encodeна нем.теперь, увидев
.encodeв байтовой строке Python 2 сначала пытается неявно преобразовать ее в текст (a
вы можете попробовать этот
import sys reload(sys) sys.setdefaultencoding("utf-8")или
вы можете попробовать следующие
добавить следующую строку в верхней части файла.py.
# -*- coding: utf-8 -*-
Если вы используете Python строковый литерал является Unicode, префикс его с
u:Python 2.7.2 (default, Jan 14 2012, 23:14:09) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> "你好".encode("utf8") Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) >>> u"你好".encode("utf8") '\xe4\xbd\xa0\xe5\xa5\xbd'более дальнеишее чтение: Unicode HOWTO.
вы используете
u"你好".encode('utf8')для кодирования строки Юникода. Но если вы хотите представить"你好", вы должны расшифровать его. Так же, как:"你好".decode("utf8")вы получите то, что вы хотите. Возможно, вам стоит узнать больше о encode & decode.
в случае, если вы имеете дело с Unicode, иногда вместо
encode('utf-8'), вы также можете пытаться игнорировать специальные символы, например"你好".encode('ascii','ignore')или
something.decode('unicode_escape').encode('ascii','ignore')как предложил здесь.не особенно полезно в этом примере, но может работать лучше в других сценариях, когда невозможно преобразовать некоторые специальные символы.
в качестве альтернативы вы можете рассмотреть замена конкретного символа с помощью
replace().
если вы запускаете интерпретатор python из оболочки в Linux или аналогичных системах (BSD, не уверен в Mac), вы также должны проверить кодировку по умолчанию для оболочки.
вызов
locale charmapиз оболочки (не интерпретатор Python) и вы должны увидеть[user@host dir] $ locale charmap UTF-8 [user@host dir] $если это не так, и вы видите что-то другое, например
[user@host dir] $ locale charmap ANSI_X3.4-1968 [user@host dir] $Python будет (по крайней мере, в некоторых случаях, например, в моем) наследовать кодировку оболочки и не сможет печатать (некоторые? все?) символ Юникода. Собственная кодировка Python по умолчанию, которую вы видите и контролируете через
sys.getdefaultencoding()иsys.setdefaultencoding()в этом случае игнорируется.если вы обнаружите, что у вас есть эта проблема, вы можете исправить это с помощью
[user@host dir] $ export LC_CTYPE="en_EN.UTF-8" [user@host dir] $ locale charmap UTF-8 [user@host dir] $(или альтернативно выберите любую клавиатуру, которую вы хотите вместо en_EN.) Вы также можете редактировать
/etc/locale.conf(или какой-либо файл управляет определением локали в вашей системе), чтобы исправить это.
Comments