Python unicode в терминале Mac os X

может кто-нибудь объяснит мне эту странную вещь:

когда в оболочке python я набираю следующую кириллическую строку:

>>> print 'абвгд'
абвгд

но когда я типа:

>>> print u'абвгд'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)

поскольку первый Тринг вышел правильно, я считаю, что мой терминал OS X может представлять unicode, но, оказывается, он не может во втором случае. Почему ?

6 ответов


>>> print 'абвгд'
абвгд

при вводе некоторые символы, ваш терминал решает, как эти символы представлены в приложении. Ваш терминал может дать символы приложению, закодированные как utf-8, ISO-8859-5 или даже что-то, что понимает только ваш терминал. Python получает эти символы в виде некоторой последовательности байтов. Затем python печатает эти байты так, как они есть, и ваш терминал интерпретирует их каким-то образом для отображения символов. Поскольку ваш терминал обычно интерпретирует байты так же, как он кодировал их раньше, все отображается так, как вы его ввели.

>>> u'абвгд'

здесь вы вводите некоторые символы, которые поступают в интерпретатор python в виде последовательности байтов, возможно, закодированных каким-то образом терминалом. С u префикс python пытается преобразовать эти данные в unicode. Чтобы сделать это правильно, python должен знать, какую кодировку использует ваш терминал. В вашем случае похоже, что Python догадывается, что ваша кодировка терминалов будет ASCII, но полученная данные не соответствуют этому, поэтому вы получаете ошибку кодирования.

прямой способ создания строк unicode в интерактивном сеансе был бы таким:

>>> us = 'абвгд'.decode('my-terminal-encoding')

в файлы, вы также можете указать кодировку файла с помощью специальной строки:

# -*- encoding: ISO-8859-5 -*-
us = u'абвгд'

для других способов установить кодировку ввода по умолчанию вы можете посмотреть на sys.setdefaultencoding(...) или sys.stdin.encoding.


начиная с Python 2.6, вы можете использовать переменную окружения PYTHONIOENCODING чтобы сообщить Python, что ваш терминал поддерживает UTF-8. Самый простой способ сделать это постоянным-добавить следующую строку в ваш ~/.bash_profile:

export PYTHONIOENCODING=utf-8

Terminal.app showing unicode output from Python


в дополнение к обеспечению того, что ваш терминал OS X установлен в UTF-8, вы можете установить кодировку python sys по умолчанию в UTF-8 или лучше. Создайте файл в /Library/Python/2.5/site-packages под названием sitecustomize.py. В этом файле ставим:

import sys
sys.setdefaultencoding('utf-8')

на setdefaultencoding метод доступен только модулем сайта и удаляется из пространство имен sys после завершения запуска. Таким образом, вам нужно будет запустить новый интерпретатор python, чтобы изменения вступили в силу. Можно проверить текущее значение по умолчанию кодирование в любое время после запуска с помощью sys.getdefaultencoding().

если символы еще не unicode, и вам нужно преобразовать их, используйте decode метод в строке для декодирования текста из какой-либо другой кодировки в unicode... лучше всего указать, какая кодировка:

s = 'абвгд'.decode('some_cyrillic_charset') # makes the string unicode
print s.encode('utf-8') # transform the unicode into utf-8, then print it

кроме того, убедитесь, что кодировка терминала установлена в Unicode / UTF-8 (а не ascii, который, похоже, является вашей настройкой):

http://www.rift.dk/news.php?item.7.6


объект unicode должен быть закодирован, прежде чем его можно будет отобразить на некоторых консолях. Попробуй!--2-->

u'абвгд'.encode()

вместо того, чтобы кодировать Юникод в строковый объект (скорее всего, используя utf8 в качестве кодировки по умолчанию, но зависит от вашей конфигурации python)


'абвгд' не является строкой юникода

u'абвгд' - строка Юникода

вы не можете печатать строки unicode без их кодирования. Когда вы имеете дело со строками в своем приложении, вы хотите убедиться, что любой вход декодирован и любой выход закодирован. Таким образом, ваше приложение будет иметь дело только со строками unicode внутри и выводить строки в UTF8.

Для справки:

>>> 'абвгд'.decode('utf8') == u'абвгд'
>>> True