Не могу декодировать строку utf-8 в python на os x Terminal.app - PullRequest
4 голосов
/ 27 апреля 2009

У меня есть Terminal.app, настроенный на прием utf-8, и в bash я могу набирать символы юникода, копировать и вставлять их, но если я запускаю оболочку python, я не могу, и если я пытаюсь декодировать юникод, я получаю ошибки:

>>> wtf = u'\xe4\xf6\xfc'.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
>>> wtf = u'\xe4\xf6\xfc'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

Кто-нибудь знает, что я делаю не так?

Ответы [ 4 ]

18 голосов
/ 27 апреля 2009

Я думаю, что есть кодирование / декодирование путаницы повсюду. Вы начинаете с объекта Unicode:

u'\xe4\xf6\xfc'

Это объект Unicode, три символа - это кодовые точки Unicode для "äöü". Если вы хотите превратить их в Utf-8, вы должны кодировать их:

>>> u'\xe4\xf6\xfc'.encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'

Результирующие шесть символов являются представлением Utf-8 слова «äöü».

Если вы звоните decode(...), вы пытаетесь интерпретировать символы как некоторую кодировку, которую все еще необходимо преобразовать в юникод. Так как это уже Unicode, это не работает. Ваш первый вызов пытается преобразование Ascii в Unicode, второй вызов преобразование Utf-8 в Unicode. Так как u'\xe4\xf6\xfc' не является ни действительным Ascii, ни действительным Utf-8, эти попытки преобразования завершаются неудачей.

Дальнейшая путаница может возникнуть из-за того факта, что '\xe4\xf6\xfc' также является кодировкой Latinja / ISO-8859-1 "äöü". Если вы пишете обычную строку Python (без начального «u», помечающего ее как Unicode), вы можете преобразовать ее в объект Unicode с помощью decode('latin1'):

>>> '\xe4\xf6\xfc'.decode('latin1')
u'\xe4\xf6\xfc'
4 голосов
/ 27 апреля 2009

Я думаю, что у вас есть кодирование и декодирование в обратном направлении. Вы кодируете Unicode в поток байтов и декодируете поток байтов в Unicode.

Python 2.6.1 (r261:67515, Dec  6 2008, 16:42:21) 
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> wtf = u'\xe4\xf6\xfc'
>>> wtf
u'\xe4\xf6\xfc'
>>> print wtf
äöü
>>> wtf.encode('UTF-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'
>>> print '\xc3\xa4\xc3\xb6\xc3\xbc'.decode('utf-8')
äöü
3 голосов
/ 27 апреля 2009
>>> wtf = '\xe4\xf6\xfc'
>>> wtf
'\xe4\xf6\xfc'
>>> print wtf
���
>>> print wtf.decode("latin-1")
äöü
>>> wtf_unicode = unicode(wtf.decode("latin-1"))
>>> wtf_unicode
u'\xe4\xf6\xfc'
>>> print wtf_unicode
äöü
2 голосов
/ 27 апреля 2009

Раздел Unicode вводного руководства хорошо объясняет это:

Для преобразования строки Unicode в 8-битную строку с использованием определенной кодировки объекты Unicode предоставляют метод encode (), который принимает один аргумент - имя кодировки. Предпочтительными являются строчные имена для кодировок.

>>> u"äöü".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...