Потерял с кодировками (оболочка и акценты) - PullRequest
5 голосов
/ 03 ноября 2011

У меня проблемы с кодировками. Я использую версию

Python 2.7.2+ (по умолчанию, 4 октября 2011 г., 20:03:08) [GCC 4.6.1] на linux2

У меня есть символы с акцентами вроде é à. В моих скриптах используется кодировка utf-8

#!/usr/bin/python
# -*- coding: utf-8 -*-

Пользователи могут вводить строки с использованием raw_input () с помощью.

def rlinput(prompt, prefill=''):
    readline.set_startup_hook(lambda: readline.insert_text( prefill))
    try:
        return raw_input(prompt)
    finally:
        readline.set_startup_hook()

вызывается в основном цикле 'псевдо' оболочки

while to_continue : 
    to_continue, feedback = action( unicode(rlinput(u'todo > '),'utf-8') )
    os.system('clear')
    print T, u"\n" + feedback

Данные хранятся в файлах как рассол.

Мне удалось заставить приложение работать, но в конце концов я получил глупые вещи вроде

основной файл:

class Task()
...
def __str__(self):
    r = (u"OK" if self._done else u"A faire").ljust(8) + self.getDesc()
    return r.encode('utf-8')

и так в файле оболочки:

feedback = jaune + str(t).decode('utf-8') + vert + u" supprimée"

Вот где я понимаю, что могу ошибаться с кодированием / декодированием. Поэтому я попытался декодировать напрямую в rlinput, но не получилось. Я прочитал какой-то пост в stackoverflow, перечитал http://docs.python.org/library/codecs.html В ожидании моей книги по питону я заблудился: /

Я думаю, что много плохого кода, но мой вопрос здесь связан только с кодировкой issus. Вы можете найти код здесь: (большинство комментариев на французском языке, извините, это для личного использования, и я новичок, вам также понадобится yapsy - http://yapsy.sourceforge.net/) (затем настройте пути, затем в py_todo: ./ todo_shell.py): http://bit.ly/rzp9Jm

Ответы [ 2 ]

2 голосов
/ 03 ноября 2011

Стандартный ввод и вывод основаны на байтах для всех систем Unix. Вот почему вы должны вызвать функцию unicode, чтобы получить для них строки символов. Ошибка декодирования указывает, что входящие байты не являются действительными UTF-8.

По сути, проблема заключается в допущении кодировки UTF-8, что не гарантируется. Подтвердите это, изменив кодировку в вашем вызове unicode на 'ISO-8859-1' или изменив кодировку символов вашего эмулятора терминала на UTF-8. (Putty поддерживает это в меню «Перевод».)

Если приведенный выше эксперимент подтверждает это, ваша задача - поддержать языковой стандарт пользователя и определить правильную кодировку или, возможно, заставить пользователя объявить кодировку в аргументе или конфигурации командной строки. Переменная окружения $LANG - это лучшее, что вы можете сделать без явного объявления, и я считаю, что это плохой показатель желаемой кодировки символов.

0 голосов
/ 04 ноября 2011

Как подсказал @wberry, я проверил кодировки: ок

$ file --mime-encoding todo_shell.py task.py todo.py
todo_shell.py: utf-8
task.py:       utf-8
todo.py:       utf-8
$ echo $LANG
fr_FR.UTF-8
$ python -c "import sys; print sys.stdin.encoding"
UTF-8

Как @eryksun предложил в качестве расшифрованного пользовательского ввода (+ закодировать строки, переданные ранее) (решил некоторые проблемы, если у меня хорошая память) (будет проверено позже):

def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text( prefill.encode(sys.stdin.encoding) ))
try:
    return raw_input( prompt ).decode( sys.stdin.encoding )
finally:
    readline.set_startup_hook()

У меня все еще были проблемы, но мой вопрос не был четко определен, поэтому я не могу получить четкий ответ. Теперь я чувствую себя менее потерянным и имею указания искать Спасибо!

РЕДАКТИРОВАТЬ: я заменил str методы на Unicode , и это убило некоторые (все?) Проб.

Спасибо @eryksun за советы. (эта ссылка помогла мне: Python __str__ против __unicode __ )

...