Юникод Python в Mac OS X терминал - PullRequest
7 голосов
/ 28 мая 2009

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

Когда в оболочке 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 ]

16 голосов
/ 28 мая 2009
>>> print 'абвгд'
абвгд

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

>>> u'абвгд'

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

Прямой способ создания Unicode-строк в интерактивном сеансе будет выглядеть примерно так:

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

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

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

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

13 голосов
/ 29 марта 2012

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

export PYTHONIOENCODING=utf-8

Terminal.app showing unicode output from Python

9 голосов
/ 28 мая 2009

В дополнение к тому, что ваш терминал 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().

Если символы еще не являются юникодом и вам нужно преобразовать их, используйте метод 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
3 голосов
/ 28 мая 2009

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

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

0 голосов
/ 28 мая 2009

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

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

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

Для справки:

>>> 'абвгд'.decode('utf8') == u'абвгд'
>>> True
0 голосов
/ 28 мая 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...