У меня проблема с кодированием переменной пути и ее вставкой в базу данных SQLite . Я попытался решить эту проблему с помощью функции кодирования ("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()
функции? Я часто с этим борюсь.
РЕДАКТИРОВАТЬ:
Этот оператор execute () вызвал ошибку:
cur.execute("update docs set path = :fullFilePath where path = :path", locals())
Я забыл изменить кодировку переменной fullFilePath, которая страдает той же проблемой, но сейчас я очень запутался. Должен ли я использовать только unicode () или кодировать ("utf-8") или оба?
Я не могу использовать
fullFilePath = unicode(fullFilePath.encode("utf-8"))
потому что это вызывает эту ошибку:
UnicodeDecodeError: кодек ascii не может декодировать байт 0xc5 в позиции 32: порядковый номер не в диапазоне (128)
Версия Python 2.7.2
unicode
?Ответы:
Вы
encode("utf-8")
неправильно используете . Строки байтов Python (str
тип) имеют кодировку, а 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())
источник
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.str
объекты, возможно, вы смешиваете кодировки. Можешь показать результатprint repr(fullFilePath)
?cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
str
текстовое представление в байтах,unicode
текстовое представление в символах.Вы декодируете текст из байтов в юникод и кодируете юникод в байты с некоторой кодировкой.
То есть:
>>> 'abc'.decode('utf-8') # str to unicode u'abc' >>> u'abc'.encode('utf-8') # unicode to str 'abc'
UPD сентябрь 2020 : ответ был написан, когда в основном использовался Python 2. В Python 3,
str
был переименован вbytes
, иunicode
был переименован вstr
.>>> b'abc'.decode('utf-8') # bytes to str 'abc' >>> 'abc'.encode('utf-8'). # str to bytes b'abc'
источник
unicode
речь идет о буквах или символах, или в более общем смысле: руны, в то время какstr
представляют собой строку байтов в определенной кодировке, которую вы должныdecode
(очевидно, в правильной кодировке) получить определенные руны'str' object has no attribute 'decode'
Убедитесь, что вы установили настройки локали прямо перед запуском скрипта из оболочки, например
$ 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
.источник