Использование функций unicode () и encode () в Python

68

У меня проблема с кодировкой переменной пути и вставка ее в базу данных SQLite. Я попытался решить эту проблему с помощью функции encode ( "utf-8" ), которая не помогла. Затем я использовал функцию unicode(), которая дает мне тип unicode.

print type(path)                  # <type 'unicode'>
path = path.replace("one", "two") # <type 'str'>
path = path.encode("utf-8")       # <type 'str'> strange
path = unicode(path)              # <type 'unicode'>

Наконец, я получил тип unicode, но у меня все еще есть та же ошибка, которая присутствовала, когда тип переменной пути был str

sqlite3.ProgrammingError: вы не должны использовать 8-битные байты, если вы используете text_factory, который может интерпретировать 8-битные байты (например, text_factory = str). Настоятельно рекомендуется, чтобы вы вместо этого просто переключите свое приложение на строки Unicode.

Не могли бы вы помочь мне решить эту ошибку и объяснить правильное использование функций encode("utf-8") и unicode()? Я часто борюсь с ним.

EDIT:

Этот оператор execute() вызвал ошибку:

cur.execute("update docs set path = :fullFilePath where path = :path", locals())

Я забыл изменить кодировку переменной fullFilePath, которая страдает одной и той же проблемой, но теперь я совершенно смущен. Должен ли я использовать только unicode() или encode ( "utf-8" ) или оба?

Я не могу использовать

fullFilePath = unicode(fullFilePath.encode("utf-8"))

потому что он вызывает эту ошибку:

UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xc5 в позиции 32: порядковый номер не в диапазоне (128)

Версия для Python - 2.7.2

  • 0
    где код, который вызывает ошибку?
  • 2
    На ваш точный вопрос уже дан ответ: [ stackoverflow.com/questions/2392732/… [1]: stackoverflow.com/questions/2392732/…
Показать ещё 4 комментария
Теги:
string
unicode
encoding

3 ответа

71
Лучший ответ

Вы используете encode("utf-8") неправильно. Строки байтов Python (str type) имеют кодировку, Unicode - нет. Вы можете преобразовать строку Unicode в строку байтов Python с помощью uni.encode(encoding), и вы можете преобразовать строку байта в строку Unicode, используя s.decode(encoding) (или, что то же самое, unicode(s, encoding)).

Если fullFilePath и path в настоящее время являются str, вы должны выяснить, как они закодированы. Например, если текущая кодировка является utf-8, вы должны использовать:

path = path.decode('utf-8')
fullFilePath = fullFilePath.decode('utf-8')

Если это не исправить, актуальной проблемой может быть то, что вы не используете строку Unicode в своем вызове execute(), попробуйте изменить ее на следующее:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
  • 0
    Этот оператор fullFilePath = fullFilePath.decode("utf-8") прежнему вызывает ошибку UnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: ordinal not in range(128) . fullFilePath - это комбинация типа str и строки, взятая из текстового столбца таблицы db, которая должна быть в кодировке utf-8.
  • 0
    Согласно этому, но это может быть UTF-8, UTF-16BE или UTF-16LE. Могу ли я узнать это как-нибудь?
Показать ещё 6 комментариев
89

str - текстовое представление в байтах, unicode - текстовое представление в символах.

Вы декодируете текст из байтов в unicode и кодируете unicode в байты с некоторой кодировкой.

То есть:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc' 
  • 3
    Благодарю вас. очень полезная информация
  • 0
    Очень чистый ответ, очень умный спасибо
Показать ещё 1 комментарий
1

Убедитесь, что вы установили свои языковые настройки прямо перед запуском script из оболочки, например

$ locale -a | grep "^en_.\+UTF-8"
en_GB.UTF-8
en_US.UTF-8
$ export LC_ALL=en_GB.UTF-8
$ export LANG=en_GB.UTF-8

Документы: man locale, man setlocale.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню