Строки Python Unicode и интерактивный интерпретатор Python

StackOverflow https://stackoverflow.com/questions/2421145

Вопрос

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

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

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

Это нормально.А ведь строки, набранные в интерпретаторе, действительно у вас за спиной кодируются?При условии, что я правильно понимаю строки в 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'
Это было полезно?

Решение

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

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

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

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

тогда как внутри Возвышенный текст вы получите что-то вроде

>>> import sys
>>> sys.stdin.encoding
'utf-8'

Другие советы

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

>>> print '\xa4'.decode('cp437')
ñ

Вы запутались, потому что редактор и интерпретатор сами используют разные кодировки.Интерпретатор 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'

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top