Я создаю простую игру, предназначенную для того, чтобы предложить пользователю перевод греческого слова на английский. Например:
cow: # here, the gamer would answer with *η αγελάδα* in order to score one point.
Я использую вспомогательную функцию для чтения и декодирования из текстового файла. Я делаю это, используя следующий код в указанной функции:
# The variable filename refers to my helper function's sole parameter, it takes the
# above mentioned txt file as an argument.
words_text = codecs.open(filename, 'r', 'utf-8')
Эта вспомогательная функция затем читает каждую строку. Линии напоминают что-то вроде этого:
# In stack data, when I debug, it reads as u"\η αγελάδα - cow\r\n".
u"\u03b7 \u03b1\u03b3\u03b5\u03bb\u03ac\u03b4\u03b1 - cow\r\n"
Однако первая строка файла при чтении имеет нежелательный префикс, ueff -:
# u"\ufeffη αγελάδα - cow\r\n"
u"\ufeff\u03b7 \u03b1\u03b3\u03b5\u03bb\u03ac\u03b4\u03b1 - cow\r\n"
Примечание. Изучив ответ Марка, я обнаружил, что предварительно добавленный объект (ueff) является сигнатурой спецификации (используется для отличия UTF-8 от других кодировок).
Это небольшая проблема, и я не уверен, как ее убрать самым аккуратным образом. В любом случае, моя вспомогательная функция затем создает и возвращает новый словарь, который выглядит примерно так:
{u'\u03b7 \u03b1\u03b3\u03b5\u03bb\u03ac\u03b4\u03b1': 'cow'}
Затем в своей основной функции я использую следующее для хранения ввода пользователя:
# This is the code for the prompt I noted at the beginning.
# The variable gr_en_dict is the dictionary noted right above.
for key in gr_en_dict:
user_reply = raw_input('%s: ' % (gr_en_dict[key])).decode(sys.stdout.encoding)
Затем я сравниваю значение ввода пользователя с соответствующим ключом в словаре:
# I imported unicodedata as ud.
if ud.normalize('NFC', user_reply) == ud.normalize('NFC', key):
score += 1
В ответ на вопрос, похожий на мой, пользователь ΤΖΩΤΖΙΟΥ сказал импортировать модуль unicodedata и вызвать метод нормализации (что я и сделал в приведенном выше коде), но я подозреваю, что в этом нет необходимости. К сожалению, этот шаг программы не имеет значения только потому, что у меня есть проблема с декодированием ввода пользователя. Чтобы продемонстрировать, когда я печатаю каноническое строковое представление user_reply и соответствующего ключа в моем словаре [используя встроенную функцию repr ()], я получаю следующий результат:
ввод пользователя (user_reply):
u'? \u03b1?\u03b5??\u03b4\u03b1'
Если я печатаю ввод пользователя без функции repr (), это выглядит так:
? α?ε??δα
ключ в моем словаре:
u'\u03b7 \u03b1\u03b3\u03b5\u03bb\u03ac\u03b4\u03b1'
Если я печатаю его без repr (), я получаю ошибку:
UnicodeEncodeError: 'charmap' codec can't encode character u'\u03b7' in position 0: character maps to <undefined>
Обратите внимание на вопросительные знаки на вводе пользователя и ошибку, которую я получаю, когда пытаюсь напечатать собственно греческое слово. Похоже, в этом суть моей проблемы.
Итак, что именно мне нужно сделать, чтобы декодировать введенные пользователем данные и правильно отобразить все греческие символы?
При использовании моей родной кодовой страницы:
C:\>chcp
Active code page: 437
C:\>\python25\python
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout.encoding
'cp437'
>>> print '? α?ε??δα'
? α?ε??δα
>>>
При использовании греческой кодовой страницы: (как ни странно, она отображается правильно только тогда, когда я сначала копирую ее в буфер обмена, а затем вставляю в приложение с типом слова. Я бы разместил изображение того, что он на самом деле печатает, в консоли по умолчанию, но Для этого мне не хватает репутации.)
C:\>chcp 869
Active code page: 869
C:\>\python25\python
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout.encoding
'cp869'
>>> print ' η αγελάδα'
η αγελάδα
>>> print 'η αγελάδα'
η αγελάδα
>>>
UP: Мне пришлось изменить шрифт консоли по умолчанию на Lucida Console. Это решило мое расхождение.