Строки Python Unicode и интерактивный интерпретатор Python - PullRequest
4 голосов
/ 11 марта 2010

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

Таким образом, python pre 3.0 имеет два типа для строк, а именно: str (байтовые строки) и unicode, которые оба получены из basestring.Тип по умолчанию для строк: str.

str. Объекты не имеют понятия о фактической кодировке, они просто байты.Либо вы сами закодировали строку юникода и, следовательно, знаете, в какой они кодировке, либо вы прочитали поток байтов, кодировку которых вы также знаете заранее (независимо).Вы можете угадать кодировку байтовой строки, кодировка которой вам неизвестна, но надежного способа выяснить это просто не существует.Лучше всего, чтобы вы декодировали рано, везде использовали в коде юникод, а кодировали поздно.

Это нормально.Но строки, введенные в интерпретатор, действительно зашифрованы для вас за вашей спиной?При условии, что мое понимание строк в Python правильное, какой метод / настройка python использует для принятия этого решения?

Источником моей путаницы являются различные результаты, которые я получаю, когда пытаюсь сделать то же самое на python моей системыустановки, и на встроенной консоли моего редактора Python.

 # Editor (Sublime Text)
 >>> s = "La caña de España"
 >>> s
 'La ca\xc3\xb1a de Espa\xc3\xb1a'
 >>> s.decode("utf-8")
 u'La ca\xf1a de Espa\xf1a'
 >>> sys.getdefaultencoding()
 'ascii'

 # Windows python interpreter
 >>> s= "La caña de España"
 >>> s
 'La ca\xa4a de Espa\xa4a'
 >>> s.decode("utf-8")
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "C:\Python25\lib\encodings\utf_8.py", line 16, in decode
     return codecs.utf_8_decode(input, errors, True)
 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa4 in position 5: unexpected code byte
 >>> sys.getdefaultencoding()
 'ascii'

Ответы [ 3 ]

7 голосов
/ 11 марта 2010

Позвольте мне расширить ответ Игнасио: в обоих случаях между Python и вами существует дополнительный слой: в одном случае это Sublime Text , а в другом - cmd.exe. Разница в поведении вы видите не из-за Python, а из-за разных кодировок, используемых Sublime Text (как кажется utf-8) и cmd.exe (cp437).

Итак, когда вы набираете ñ, Sublime Text отправляет '\xc3\xb1' в Python, тогда как cmd.exe отправляет \xa4. [Я просто здесь, опуская детали, которые не имеют отношения к вопросу.].

Тем не менее, Python знает об этом. С cmd.exe вы, вероятно, получите что-то вроде:

>>> import sys
>>> sys.stdin.encoding
'cp437'

, тогда как в Sublime Text вы получите что-то вроде

>>> import sys
>>> sys.stdin.encoding
'utf-8'
3 голосов
/ 11 марта 2010

Интерпретатор использует собственную кодировку командной строки для ввода текста. В вашем случае это CP437:

>>> print '\xa4'.decode('cp437')
ñ
0 голосов
/ 11 марта 2010

Вы запутались, потому что редактор и интерпретатор сами используют разные кодировки. Интерпретатор python использует вашу систему по умолчанию (в данном случае cp437), а ваш редактор использует utf-8.

Обратите внимание, что разница исчезнет, ​​если вы укажете строку в юникоде, например:

# Windows python interpreter
>>> s = "La caña de España"
>>> s
'La ca\xa4a de Espa\xa4a'
>>> s = u"La caña de España"
>>> s
u'La ca\xf1a de Espa\xf1a'

Мораль этой истории? Кодировки сложны. Убедитесь, что вы знаете, в какой кодировке находятся ваши исходные файлы, или играйте безопасно, всегда используя экранированную версию специальных символов.

...