Mam problem z zakodowaniem zmiennej ścieżki i wstawieniem jej do bazy SQLite . Próbowałem to rozwiązać za pomocą funkcji kodowania („utf-8”), która nie pomogła. Następnie użyłem funkcji unicode (), która daje mi typ 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'>
Wreszcie uzyskałem typ unicode , ale nadal mam ten sam błąd, który był obecny, gdy typ zmiennej ścieżki to str
sqlite3.ProgrammingError: Nie możesz używać 8-bitowych bajtów, chyba że używasz text_factory, który może interpretować 8-bitowe bajty (jak text_factory = str). Zdecydowanie zaleca się, aby zamiast tego po prostu przełączyć aplikację na ciągi znaków Unicode.
Czy możesz mi pomóc rozwiązać ten błąd i wyjaśnić prawidłowe użycie encode("utf-8")
i unicode()
funkcje? Często z tym walczę.
EDYTOWAĆ:
Ta instrukcja execute () spowodowała błąd:
cur.execute("update docs set path = :fullFilePath where path = :path", locals())
Zapomniałem zmienić kodowanie zmiennej fullFilePath , która cierpi na ten sam problem, ale jestem teraz dość zdezorientowany. Należy używać tylko unicode () lub kodowanie ( "UTF-8") lub obu?
Nie mogę użyć
fullFilePath = unicode(fullFilePath.encode("utf-8"))
ponieważ wywołuje ten błąd:
UnicodeDecodeError: kodek „ascii” nie może zdekodować bajtu 0xc5 na pozycji 32: numer porządkowy poza zakresem (128)
Wersja Pythona to 2.7.2
unicode
?Odpowiedzi:
Używasz
encode("utf-8")
nieprawidłowo. Ciągi bajtów Pythona (str
typ) mają kodowanie, a Unicode nie. Możesz przekonwertować ciąg znaków Unicode na ciąg bajtów języka Python za pomocąuni.encode(encoding)
, a ciąg bajtów można przekonwertować na ciąg znaków Unicode za pomocąs.decode(encoding)
(lub równoważnieunicode(s, encoding)
).Jeśli
fullFilePath
ipath
obecnie sąstr
typem, powinieneś dowiedzieć się, jak są one kodowane. Na przykład, jeśli bieżącym kodowaniem jest utf-8, użyjesz:path = path.decode('utf-8') fullFilePath = fullFilePath.decode('utf-8')
Jeśli to nie pomoże, rzeczywisty problem może polegać na tym, że w
execute()
wywołaniu nie używasz ciągu znaków Unicode , spróbuj zmienić go na następujący:cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
źródło
fullFilePath = fullFilePath.decode("utf-8")
nadal budzi błądUnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: ordinal not in range(128)
. fullFilePath to kombinacja typu str i string pobranych z kolumny tekstowej tabeli db, która powinna być kodowana w formacie UTF-8.str
obiekty, możesz mieszać kodowania. Czy możesz pokazać wynikprint repr(fullFilePath)
?cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
str
jest reprezentacją tekstu w bajtach,unicode
jest reprezentacją tekstu w znakach.Dekodujesz tekst z bajtów na Unicode i kodujesz Unicode na bajty z pewnym kodowaniem.
To jest:
>>> 'abc'.decode('utf-8') # str to unicode u'abc' >>> u'abc'.encode('utf-8') # unicode to str 'abc'
UPD wrzesień 2020 : Odpowiedź została napisana, gdy używany był głównie Python 2. W Pythonie 3
str
zmieniono nazwę nabytes
iunicode
nastr
.>>> b'abc'.decode('utf-8') # bytes to str 'abc' >>> 'abc'.encode('utf-8'). # str to bytes b'abc'
źródło
unicode
mówi o liter lub symboli, lub bardziej ogólnie: runy natomiaststr
reprezentuje ciąg bajtów w pewnym kodowania, które należydecode
(oczywiście w prawidłowym kodowaniu), aby uzyskać szczegółowe runy'str' object has no attribute 'decode'
Upewnij się, że ustawiłeś swoje ustawienia regionalne bezpośrednio przed uruchomieniem skryptu z powłoki, np
$ 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
Dokumenty:
man locale
,man setlocale
.źródło