Jak naprawić: „UnicodeDecodeError: kodek„ ascii ”nie może dekodować bajtu”


459
as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

Jak to naprawić?

W niektórych innych statycznych aplikacjach blogowych opartych na języku Python chiński post może zostać pomyślnie opublikowany. Takich jak ta aplikacja: http://github.com/vrypan/bucket3 . Na mojej stronie http://bc3.brite.biz/ chiński post można pomyślnie opublikować.


Odpowiedzi:


569

tl; dr / szybka poprawka

  • Nie dekoduj / koduj willy nilly
  • Nie zakładaj, że twoje łańcuchy są zakodowane w UTF-8
  • Spróbuj przekonwertować ciągi znaków na ciągi Unicode tak szybko, jak to możliwe w kodzie
  • Napraw swoje ustawienia regionalne: jak rozwiązać UnicodeDecodeError w Pythonie 3.6?
  • Nie ulegaj pokusie używania szybkich reloadhacków

Unicode Zen w Python 2.x - wersja długa

Nie widząc źródła trudno jest poznać przyczynę, więc będę musiał mówić ogólnie.

UnicodeDecodeError: 'ascii' codec can't decode bytezazwyczaj dzieje się, gdy próbujesz przekonwertować Python 2.x, strktóry zawiera nie-ASCII na ciąg Unicode, bez określania kodowania oryginalnego ciągu.

W skrócie, ciągi Unicode są całkowicie oddzielnym typem ciągów Python, które nie zawierają żadnego kodowania. Przechowują tylko kody punktowe Unicode i dlatego mogą przechowywać dowolny punkt Unicode z całego spektrum. Ciągi zawierają zakodowany tekst, jednak UTF-8, UTF-16, ISO-8895-1, GBK, Big5 itp. Ciągi są dekodowane do Unicode, a Unicode są kodowane do ciągów . Pliki i dane tekstowe są zawsze przesyłane w zakodowanych ciągach.

Autorzy modułu Markdown prawdopodobnie używają unicode()(gdzie zgłaszany jest wyjątek) jako jakościowej bramki do reszty kodu - przekonwertuje ASCII lub ponownie zawinie istniejące ciągi Unicode na nowy ciąg Unicode. Autorzy Markdown nie znają kodowania przychodzącego łańcucha, więc będą polegać na tobie, aby zdekodować łańcuchy na łańcuchy Unicode przed przekazaniem do Markdown.

Ciągi znaków Unicode można zadeklarować w kodzie za pomocą uprzedrostka ciągów znaków. Na przykład

>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>

Ciągi znaków Unicode mogą również pochodzić z plików, baz danych i modułów sieciowych. Kiedy tak się dzieje, nie musisz się martwić o kodowanie.

Gotchas

Konwersja z strna Unicode może się zdarzyć, nawet jeśli nie zadzwonisz jawnie unicode().

Następujące scenariusze powodują UnicodeDecodeErrorwyjątki:

# Explicit conversion without encoding
unicode('€')

# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')

# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'

# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'         

Przykłady

Na poniższym diagramie można zobaczyć, jak słowo cafézostało zakodowane w kodowaniu „UTF-8” lub „Cp1252” w zależności od typu terminala. W obu przykładach cafjest po prostu zwykłym ascii. W UTF-8 éjest kodowany przy użyciu dwóch bajtów. W „Cp1252” é ma wartość 0xE9 (która jest również wartością punktową Unicode (to nie przypadek)). Wywoływane decode()jest prawidłowe i konwersja na kodowanie Unicode w języku Python kończy się powodzeniem: Schemat ciągu przetwarzanego na ciąg znaków Unicode w języku Python

Na tym schemacie decode()jest wywoływany za pomocą ascii(co jest takie samo jak wywoływanie unicode()bez podanego kodowania). Ponieważ ASCII nie może zawierać bajtów większych niż 0x7F, spowoduje to UnicodeDecodeErrorwyjątek:

Schemat ciągu konwertowanego na ciąg Unicode w języku Python z nieprawidłowym kodowaniem

Kanapka Unicode

Dobrą praktyką jest tworzenie w kodzie kanapki Unicode, w której dekodujesz wszystkie przychodzące dane do ciągów Unicode, pracujesz z Unicodes, a następnie kodujesz do strs po wyjściu. Dzięki temu nie musisz się martwić kodowaniem ciągów znaków w środku kodu.

Wejście / dekodowanie

Kod źródłowy

Jeśli chcesz upiec kod inny niż ASCII w kodzie źródłowym, po prostu utwórz ciągi Unicode, poprzedzając je ciągiem u. Na przykład

u'Zürich'

Aby umożliwić Pythonowi zdekodowanie kodu źródłowego, musisz dodać nagłówek kodowania zgodny z faktycznym kodowaniem pliku. Na przykład, jeśli plik został zakodowany jako „UTF-8”, użyłbyś:

# encoding: utf-8

Jest to konieczne tylko wtedy, gdy masz kod inny niż ASCII w kodzie źródłowym .

Akta

Zazwyczaj dane spoza ASCII są odbierane z pliku. ioModuł dostarcza TextWrapper który dekoduje plik na bieżąco, za pomocą danego encoding. Musisz użyć prawidłowego kodowania pliku - nie można go łatwo odgadnąć. Na przykład dla pliku UTF-8:

import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
     my_unicode_string = my_file.read() 

my_unicode_stringbyłby wtedy odpowiedni do przejścia do Markdown. Jeśli UnicodeDecodeErrorpochodzi z read()linii, prawdopodobnie użyłeś niewłaściwej wartości kodowania.

Pliki CSV

Moduł CSV Python 2.7 nie obsługuje znaków spoza ASCII 😩. Pomoc jest jednak pod ręką dzięki https://pypi.python.org/pypi/backports.csv .

Użyj go jak wyżej, ale przekaż do niego otwarty plik:

from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
    for row in csv.reader(my_file):
        yield row

Bazy danych

Większość sterowników baz danych Python może zwracać dane w formacie Unicode, ale zwykle wymaga niewielkiej konfiguracji. Zawsze używaj ciągów Unicode do zapytań SQL.

MySQL

W ciągu połączenia dodaj:

charset='utf8',
use_unicode=True

Na przykład

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL

Dodaj:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

HTTP

Strony internetowe można zakodować niemal w dowolnym kodowaniu. Content-typeNagłówek powinien zawierać charsetpole, aby schować w kodowaniu. Zawartość można następnie dekodować ręcznie w oparciu o tę wartość. Alternatywnie, Python-Requests zwraca Unicode w response.text.

Ręcznie

Jeśli musisz ręcznie dekodować ciągi, możesz po prostu zrobić my_string.decode(encoding), gdzie encodingjest odpowiednie kodowanie. Podano tutaj kodeki obsługiwane w języku Python 2.x: Standardowe kodowanie . Ponownie, jeśli UnicodeDecodeErrorto zrobisz, prawdopodobnie masz złe kodowanie.

Mięso Kanapki

Pracuj z Unicodes tak jak normalne napisy.

Wynik

standardowe / drukowanie

printzapisuje przez standardowy strumień. Python próbuje skonfigurować koder na standardowym wyjściu, aby Unicode były kodowane do kodowania konsoli. Na przykład, jeśli Linux powłoki na localeto en_GB.UTF-8, wyjście zostanie zakodowany UTF-8. W systemie Windows będziesz ograniczony do 8-bitowej strony kodowej.

Niepoprawnie skonfigurowana konsola, na przykład uszkodzone ustawienia regionalne, może prowadzić do nieoczekiwanych błędów drukowania. PYTHONIOENCODINGzmienna środowiskowa może wymusić kodowanie dla standardowego wyjścia.

Akta

Podobnie jak dane wejściowe, io.openmoże służyć do przezroczystej konwersji Unicodów na zakodowane ciągi bajtów.

Baza danych

Ta sama konfiguracja odczytu pozwoli na bezpośrednie pisanie Unicodów.

Python 3

Python 3 nie obsługuje bardziej Unicode niż Python 2.x, jednak jest nieco mniej zdezorientowany w tym temacie. Np. Regular strjest teraz ciągiem Unicode, a stary strjest teraz bytes.

Domyślne kodowanie to UTF-8, więc jeśli .decode()ciąg bajtów nie został podany, Python 3 używa kodowania UTF-8. Prawdopodobnie rozwiązuje to 50% problemów z Unicode.

Ponadto open()domyślnie działa w trybie tekstowym, więc zwraca zdekodowane str(Unicode). Kodowanie pochodzi z ustawień regionalnych, które zwykle mają postać UTF-8 w systemach Un * x lub 8-bitową stronę kodową, taką jak Windows-1251, w polach Windows.

Dlaczego nie powinieneś używać sys.setdefaultencoding('utf8')

To paskudny hack (jest powód, dla którego musisz go użyć reload), który tylko maskuje problemy i utrudnia migrację do Pythona 3.x. Zrozum problem, napraw główną przyczynę i ciesz się zen z Unicode. Zobacz, dlaczego NIE powinniśmy używać sys.setdefaultencoding („utf-8”) w skrypcie py? dla dalszych szczegółów


2
Dla kogoś, kto szuka odpowiedzi w języku Python 2, bardziej przydatny TLDR: użyj io.opendo odczytu / zapisu plików, użyj from __future__ import unicode_literals, skonfiguruj inne wejścia / wyjścia danych (np. Bazy danych), aby używać Unicode.
idbrii

sooo jak to naprawić? lol to nie jest problem z pisaniem skryptu - to z instalacji jednego
Matthew

@Matthew spróbuj ustawić PYTHONIOENCODING=utf-8. Jeśli to nie pomoże, musisz skontaktować się z autorem skryptu, aby naprawić jego kod.
Alastair McCormack

498

W końcu to dostałam:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Niech sprawdzę:

as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>

Powyższe pokazuje domyślne kodowanie Pythona utf8. Błąd już nie istnieje.


7
Próbuję tego, ale nie może trwale zmienić kodowania. Po wyjściu z konsoli Python i ponownym uruchomieniu kodowanie jest nadal takie samo
Macemers

37
Dzięki! Ale dlaczego musimy ponownie załadować system po jego zaimportowaniu?
Dmiters

6
@DmitryNarkevich, z powodu iluzorycznej funkcji setdefaultencoding . Jest usuwany przy starcie Pythona, ponieważ najwyraźniej nigdy nie powinien być częścią poprawnego wydania.
przed

3
Oznacza to, że nie naprawiłeś pierwotnej przyczyny. Właśnie załatałeś jakąkolwiek domniemaną konwersję
Alastair McCormack

5
@miraculixx Domyślne kodowanie Pythona 3 to UTF-8 z domyślnymi łańcuchami Unicode str, więc nie jest to opóźnienie. W Pythonie 2.x Unicode był w stanie przejściowym, więc byłoby niebezpiecznie założyć kodowanie podczas konwersji bajtów na Unicode. Dlatego domyślnym kodowaniem ASCII przez Py2 był celowy wybór i dlaczego zmiana domyślnego kodowania wymaga celowego włamania do ponownego ładowania sys. Prawidłowym sposobem na wyeliminowanie błędów kodowania w Py2 jest jednoznaczne dekodowanie i kodowanie (bajt) ciągów znaków do Unicode, gdy konwersje są konieczne - nie tylko zakładanie, że ciągi są kodowane w UTF-8.
Alastair McCormack

130

Jest to klasyczny „problem z Unicode”. Uważam, że wyjaśnienie tego jest poza zakresem odpowiedzi StackOverflow, aby całkowicie wyjaśnić, co się dzieje.

Jest to dobrze wyjaśnione tutaj .

W bardzo krótkim podsumowaniu przekazałeś coś, co jest interpretowane jako ciąg bajtów, do czegoś, co musi go zdekodować na znaki Unicode, ale domyślny kodek (ascii) zawodzi.

Prezentacja, na którą wskazałem, zawiera porady, jak tego uniknąć. Zmień swój kod w „kanapkę Unicode”. W Pythonie 2 użycie from __future__ import unicode_literalspomocy.

Aktualizacja: jak można naprawić kod:

OK - w zmiennej „source” masz trochę bajtów. Z twojego pytania nie wynika jasno, jak się tam dostali - może czytasz je z formularza internetowego? W każdym razie nie są one kodowane za pomocą ascii, ale python próbuje przekonwertować je na Unicode, zakładając, że tak jest. Musisz wyraźnie powiedzieć, co to jest kodowanie. Oznacza to, że musisz wiedzieć, co to jest kodowanie! Nie zawsze jest to łatwe i zależy wyłącznie od tego, skąd pochodzi ten ciąg. Możesz eksperymentować z niektórymi typowymi kodowaniami - na przykład UTF-8. Podaj kodowaniu unicode () drugi parametr:

source = unicode(source, 'utf-8')

1
to wciąż boli mnie głowa. panie GreenAsJade, czy możesz dać mi konkretne rozwiązanie?
rybak

1
Pytasz „jak mogę, jako użytkownik tego bloga, uniknąć tego problemu?”. A może masz pytanie „jak mogę naprawić kod, aby ten problem się nie zdarzył”?
GreenAsJade

2
mr greenasjade: gdzie powinienem umieścić „source = unicode (source, 'utf-8')”?
rybak

7
Dziwne ... po pozytywnych opiniach od ponad roku nagle dwa negatywne głosy ... Hę?
GreenAsJade

11
użyj currentFile = open(filename, 'rt', encoding='latin1')lub currentFile = open(filename, 'rt', encoding='utf-8')- patrz tutaj: stackoverflow.com/a/23917799/2047442
irudyak

42

W niektórych przypadkach po sprawdzeniu domyślnego kodowania ( print sys.getdefaultencoding()) zwraca ono, że używasz ASCII. Zmiana na UTF-8 nie działa, w zależności od zawartości zmiennej. Znalazłem inny sposób:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')

ty, to zadziałało w przypadku mojego problemu z rzucaniem przez Python UnicodeDecodeError na var = u "" "zmienny duży ciąg" ""
user2426679

AttributeError: moduł „sys” nie ma atrybutu „setdefaultencoding”
Chaine

i reload(sys)jest używany z tego konkretnego powodu.
Marcin Orłowski

1
Pracował dla mnie! DZIĘKI !
Maciej

22

Szukałem rozwiązania następującego komunikatu o błędzie:

unicodedecodeerror: kodek „ascii” nie może dekodować bajtu 0xe2 w pozycji 5454: porządek poza zakresem (128)

W końcu udało mi się to naprawić, określając „kodowanie”:

f = open('../glove/glove.6B.100d.txt', encoding="utf-8")

Szkoda, że ​​to też nie pomoże.


to rozwiązało dla mnie błąd podczas odczytu / zapisu plików .csv, nie potrzebowałem żadnych innych rzeczy wymienionych w innych odpowiedziach
user5359531

Nie rozumiem, dlaczego pozostałe odpowiedzi zawierają tak wiele szczegółów ... ale zapomnij o tym prostym rozwiązaniu. +10!
stan0

18
"UnicodeDecodeError: 'ascii' codec can't decode byte"

Przyczyna tego błędu: łańcuch_wejściowy musi być Unicode, ale podano str

"TypeError: Decoding Unicode is not supported"

Przyczyna tego błędu: próba przekształcenia łańcucha wejściowego Unicode na Unicode


Najpierw sprawdź, czy łańcuch wejściowy jest, stri w razie potrzeby przekonwertuj go na Unicode:

if isinstance(input_string, str):
   input_string = unicode(input_string, 'utf-8')

Po drugie, powyższe po prostu zmienia typ, ale nie usuwa znaków innych niż ascii. Jeśli chcesz usunąć znaki inne niż ascii:

if isinstance(input_string, str):
   input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.

elif isinstance(input_string, unicode):
   input_string = input_string.encode('ascii', 'ignore')

9

Uważam, że najlepiej jest zawsze konwertować na Unicode - ale jest to trudne do osiągnięcia, ponieważ w praktyce będziesz musiał sprawdzić i przekonwertować każdy argument na każdą pisaną funkcję i metodę, która obejmuje pewną formę przetwarzania łańcucha.

Wymyśliłem więc następujące podejście, aby albo gwarantować Unicode, albo ciągi bajtów, z obu danych wejściowych. Krótko mówiąc, dołącz i użyj następujących lambdas:

# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt) 
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)

Przykłady:

text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))

Oto kilka argumentów na ten temat .


Cześć, w Pythonie 3 funkcja _u nie działa z tą wartością „Ita £”.
Martin

1
Ok, od czego zacząć od „rozumowania”? print unicode(u'Zürich', encoding="UTF-8")a potem narzekają: „O dziwo, nie można zakodować rozszerzenia Unicode w UTF8”. unicode()nie koduje; dekoduje i nie można dekodować Unicode - już jest dekodowany!
Alastair McCormack

@AlastairMcCormack Serdecznie zapraszamy do poprawy postu. Jeśli jednak wolisz posypać swoją rzekomą nadrzędnością nad wszystkimi innymi, którzy nie podzielają twojej opinii i wglądu, szczerze mówiąc, nie jestem zainteresowany. Dziękuję Ci.
miraculixx

3
@miraculixx Przepraszam, nie chciałem spotkać się jak palant. Niepotrzebne jest martwienie się o dekodowanie i kodowanie za każdym razem, gdy użyjesz ciągu znaków w kodzie.
Alastair McCormack

7

Aby rozwiązać ten problem na poziomie systemu operacyjnego w instalacji Ubuntu, sprawdź następujące elementy:

$ locale charmap

Jeśli dostaniesz

locale: Cannot set LC_CTYPE to default locale: No such file or directory

zamiast

UTF-8

następnie ustaw LC_CTYPEi LC_ALLtak:

$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"

6

Kodowanie przekształca obiekt Unicode w obiekt łańcuchowy. Myślę, że próbujesz zakodować obiekt łańcuchowy. najpierw przekonwertuj swój wynik na obiekt Unicode, a następnie zakoduj ten obiekt Unicode na „utf-8”. na przykład

    result = yourFunction()
    result.decode().encode('utf-8')

4

Miałem ten sam problem, ale nie działał w Pythonie 3. Postępowałem zgodnie z tym i rozwiązałem mój problem:

enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)

Musisz ustawić kodowanie podczas odczytywania / zapisywania pliku.


4

Wystąpił ten sam błąd i to rozwiązało mój błąd. Dzięki! Python 2 i Python 3 różniące się obsługą Unicode powodują, że marynowane pliki są dość niekompatybilne z ładowaniem. Więc użyj argumentu kodującego marynaty pytona. Poniższy link pomógł mi rozwiązać podobny problem, gdy próbowałem otworzyć marynowane dane z mojego pytona 3.7, podczas gdy mój plik został pierwotnie zapisany w wersji python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Kopiuję funkcję load_pickle w moim skrypcie i podczas ładowania mojego wywołałem load_pickle (plik pickle_file) dane wejściowe takie jak to:

input_data = load_pickle("my_dataset.pkl")

Funkcja load_pickle jest tutaj:

def load_pickle(pickle_file):
    try:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f)
    except UnicodeDecodeError as e:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f, encoding='latin1')
    except Exception as e:
        print('Unable to load data ', pickle_file, ':', e)
        raise
    return pickle_data

1
lepiej jest dołączyć definicję load_picklefunkcji do swojej odpowiedzi.
sanyash

4

To działało dla mnie:

    file = open('docs/my_messy_doc.pdf', 'rb')

3

Krótko mówiąc, aby zapewnić poprawną obsługę Unicode w Pythonie 2:

  • używać io.opendo odczytu / zapisu plików
  • posługiwać się from __future__ import unicode_literals
  • skonfiguruj inne wejścia / wyjścia danych (np. bazy danych, sieć), aby używały Unicode
  • jeśli nie możesz skonfigurować wyjść do utf-8, przekonwertuj dla nich wyjście print(text.encode('ascii', 'replace').decode())

Wyjaśnienia znajdują się w szczegółowej odpowiedzi @Alastair McCormack .


• służy io.open(path, 'r', encoding='utf-8')do odczytu plików zakodowanych w utf-8.
Bob Stein,

3

Miałem ten sam błąd, w przypadku adresów URL zawierających znaki inne niż ascii (bajty o wartości> 128) moje rozwiązanie:

url = url.decode('utf8').encode('utf-8')

Uwaga: utf-8, utf8 to po prostu aliasy. Używanie tylko „utf8” lub „utf-8” powinno działać w ten sam sposób

W moim przypadku, pracował dla mnie, w Pythonie 2.7, przypuszczam, że to przypisanie zmieniło „coś” w strwewnętrznej reprezentacji - tj. Wymusza prawidłowe dekodowanie sekwencji bajtów kopii zapasowej urli ostatecznie wstawia ciąg do utf-8 str z cała magia we właściwym miejscu. Unicode w Pythonie to dla mnie czarna magia. Mam nadzieję, że przydatne


1
Dlaczego
kres

1
Python akceptuje aliasy do kodowania nazw, próbowałem teraz i wykonałem to samo ... po prostu nie zauważyłem, że napisałem je inaczej, dodałem notatkę
Fabiano Tarlao

2

Mam ten sam problem z ciągiem „PastelerÃa Mallorca” i rozwiązałem:

unicode("Pastelería Mallorca", 'latin-1')

1

W projekcie Django (1.9.10) / Python 2.7.5 mam częste UnicodeDecodeErrorwyjątki; głównie gdy próbuję podać ciągi znaków Unicode do logowania. Stworzyłem funkcję pomocniczą dla dowolnych obiektów, która zasadniczo formatuje 8-bitowe ciągi ascii i zamienia wszelkie znaki spoza tabeli na „?”. Myślę, że nie jest to najlepsze rozwiązanie, ale ponieważ domyślnym kodowaniem jest ascii (i nie chcę go zmieniać), zrobi to:

def encode_for_logging (c, encoding = 'ascii'):
    if isinstance (c, basestring):
        return c.encode (kodowanie, „zamień”)
    elif isinstance (c, Iterable):
        c_ = []
        dla v in c:
            c_.append (encode_for_logging (v, kodowanie))
        zwróć c_
    jeszcze:
        return encode_for_logging (unicode (c))
`


1

Ten błąd występuje, gdy w naszym ciągu znajduje się kilka znaków spoza ASCII i wykonujemy dowolne operacje na tym ciągu bez odpowiedniego dekodowania. To pomogło mi rozwiązać mój problem. Czytam plik CSV z identyfikatorem kolumn, tekstem i znakami dekodującymi, jak poniżej:

train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
    print("ID :" + i[0])
    text = i[1].decode("utf-8",errors="ignore").strip().lower()
    print("Text: " + text)

0

Oto moje rozwiązanie, po prostu dodaj kodowanie. with open(file, encoding='utf8') as f

A ponieważ odczytanie pliku rękawicy zajmie dużo czasu, polecam plik rękawicy do pliku numpy. Gdy czas Netx odczytasz wagi osadzania, zaoszczędzi ci to czasu.

import numpy as np
from tqdm import tqdm


def load_glove(file):
    """Loads GloVe vectors in numpy array.
    Args:
        file (str): a path to a glove file.
    Return:
        dict: a dict of numpy arrays.
    """
    embeddings_index = {}
    with open(file, encoding='utf8') as f:
        for i, line in tqdm(enumerate(f)):
            values = line.split()
            word = ''.join(values[:-300])
            coefs = np.asarray(values[-300:], dtype='float32')
            embeddings_index[word] = coefs

    return embeddings_index

# EMBEDDING_PATH = '../embedding_weights/glove.840B.300d.txt'
EMBEDDING_PATH = 'glove.840B.300d.txt'
embeddings = load_glove(EMBEDDING_PATH)

np.save('glove_embeddings.npy', embeddings) 

Link Gist: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.