Преобразование из ASCII в UTF-8 с Python - PullRequest
3 голосов
/ 15 февраля 2010

У меня бот xmpp написан на python. Один из его плагинов способен выполнять команды ОС и отправлять вывод пользователю. Насколько я знаю, вывод должен быть похож на юникод, чтобы отправлять его по протоколу xmpp. Поэтому я попытался справиться с этим следующим образом:

output = os.popen(cmd).read() 
if not isinstance(output, unicode):
   output = unicode(output,'utf-8','ignore')
bot.send(xmpp.Message(mess.getFrom(),output))

Но когда русские символы появляются на выходе, они не очень хорошо конвертируются.

sys.getdefaultencoding() 

говорит, что кодировкой командной строки по умолчанию является 'ascii', но когда я пытаюсь сделать

output.decode('ascii') 

в консоли Python я получаю

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x92 in position 1: 
ordinal not in range(128)

ОС: Win XP, Python 2.5.4 PS: извините за мой английский: (* ​​1013 *

Ответы [ 4 ]

3 голосов
/ 15 февраля 2010

sys.getdefaultencoding() возвращает кодировку по умолчанию для Python - то есть ASCII, если вы не изменили ее. ASCII не поддерживает русские символы.

Вам необходимо выяснить, что такое кодировка фактического текста, либо вручную, либо используя языковой модуль .

Обычно что-то вроде:

import locale
encoding = locale.getpreferredencoding(do_setlocale=True)¶
2 голосов
/ 15 февраля 2010

Ascii не имеет определенных значений символов выше 127 0x7F. Возможно, вы имеете в виду кодовую страницу кириллицы? Это 866

См. http://en.wikipedia.org/wiki/Code_page

edit: поскольку этот ответ был помечен как правильный, предположительно 886 работал, но, как указывали другие ответы, 886 - не единственная кодовая страница русского языка. Если вы используете кодовую страницу, отличную от той, которая использовалась при кодировании русских символов, вы получите неверный результат.

1 голос
/ 15 февраля 2010

Вы говорите, что "" "sys.getdefaultencoding () говорит, что кодировкой командной строки по умолчанию является 'ascii'" ""

sys.getdefaultencoding НИЧЕГО не говорит о кодировке «командной строки».

В Windows sys.stdout.encoding должен выполнить эту работу. На моей машине он содержит cp850, когда Python запускается в окне командной строки, и cp1252 в IDLE. Ваши должны содержать cp866 и cp1251 соответственно.

Обновление Вы говорите, что вам все еще нужен cp866 в режиме ожидания. Обратите внимание:

IDLE 2.6.4      
>>> import os
>>> os.popen('chcp').read()
'Active code page: 850\n'
>>>

Поэтому, когда ваше приложение запускается, проверьте, работаете ли вы в Windows, и если да, проанализируйте результат os.popen('chcp').read(). Текст перед :, вероятно, зависит от локали. codepage = result.split()[-1] может быть достаточно хорошим "разбором". В Unix, у которой нет разделенной личности Windows / MS-DOS, sys.stdout.encoding должно быть в порядке.

0 голосов
/ 15 февраля 2010

В Python 'cp855', 'cp866', 'cp1251', 'iso8859_5', 'koi8_r' являются разными русскими кодовыми страницами. Вам нужно будет использовать правильный, чтобы декодировать вывод popen. В консоли Windows команда 'chcp' отображает кодовую страницу, используемую командами консоли. Это не обязательно будет той же кодовой страницей, что и приложения Windows. В Windows Windows «cp437» используется для консоли, а «cp1252» используется для таких приложений, как «Блокнот».

...