2011-01-25 4 views
7

Я пытаюсь напечатать строку юникода без конкретного гексагона кодировки. Я хватаю эти данные из facebook, который имеет тип кодирования в заголовках html UTF-8. Когда я печатаю тип - он говорит свой unicode, но затем, когда я пытаюсь декодировать его с помощью unicode-escape, возникает ошибка кодирования. Почему он пытается кодировать, когда я использую метод декодирования?Функция декодирования пытается закодировать Python

Код

a='really long string of unicode html text that i wont reprint' 
print type(a) 
>>> <type 'unicode'> 
print a.decode('unicode-escape') 
>>> Traceback (most recent call last): 
    File "scfbp.py", line 203, in myFunctionPage 
    print a.decode('unicode-escape') 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 1945: ordinal not in range(128) 

ответ

8

Это не расшифровывает, что это не удается. Это потому, что вы пытаетесь отобразить результат на консоли. Когда вы используете печать, он кодирует строку, используя кодировку по умолчанию, которая является ASCII. Не используйте печать, и она должна работать.

 
>>> a=u'really long string containing \\u20ac and some other text' 
>>> type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 
u'really long string containing \u20ac and some other text' 
>>> print a.decode('unicode-escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128) 

Я бы рекомендовал использовать IDLE или какой-либо другой интерпретатор, который может выводить unicode, тогда вы не получите эту проблему.


Update: Обратите внимание, что это не то же самое, как situtation с одним меньше обратной косой черты, где она терпит неудачу во время декодирования, но с тем же сообщением об ошибке:

 
>>> a=u'really long string containing \u20ac and some other text' 
>>> type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128) 
+0

Это не повод для его ошибки. Он пытается декодировать объект unicode. Поскольку вы декодируете из двоичных данных в unicode данные, Python 2 сначала * закодирует * это, что он делает с ascii-кодеком. Это то, что терпит неудачу. –

+0

@ Lennart Regebro: На самом деле я подозреваю, что фактическим типом его строки является 'str', а не' unicode'. Посмотрите, как он инициализирует строку - обратите внимание, что нет 'u'. Я думаю, что он имеет не строку юникода, а строку * unicode-escaped * (не то же самое!). Именно это он пытается декодировать в unicode. Если моя теория правильная, я думаю, что этот ответ на самом деле правильный. –

+0

@Mark Byers: Правда, это непоследовательно, но пропустить u проще, чем печатать неверный тип. :) И ошибка согласуется с тем, что он делает. Если вы декодируете объект unicode, вы получаете ошибку кодирования. –

3

При печати на console Python пытается кодировать (преобразовывать) строку в набор символов вашего терминала. Если это не UTF-8 или что-то, что не отображает все символы в строке, оно будет скулить и бросать исключение.

Это время отвлекает меня, когда я выполняю быструю обработку данных, например, с турецкими персонажами.

Если вы работаете в python.exe через командную строку Windows, здесь вы найдете следующие решения: What encoding/code page is cmd.exe using. В принципе, вы можете изменить кодовую страницу с chcp, но это довольно громоздко. Я бы следовал Mark's advice и использовал что-то вроде IDLE.

+1

Уход за разъяснением -1? – Skurmedel

1
>>> print type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 

Почему она пытается кодировать, когда я использую метод декодирования?

Поскольку вы декодировать в Unicode, и кодировать от. Вы просто пытались декодировать строку unicode в unicode. Первое, что он делает, это попытаться преобразовать его в строку с кодеком ascii. Вот почему вы получаете:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2110' in position 3: ordinal not in range(128) 

Помните: Unicode не является кодировкой. Все остальное, как ascii, utf8, latin-1 и т. Д.

Это неявное кодирование ушло на Python 3, кстати, потому что это смущает людей.

Смежные вопросы