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!
Wie man es repariert?
In einigen anderen Python-basierten statischen Blog-Apps kann der chinesische Beitrag erfolgreich veröffentlicht werden. Wie diese App: http://github.com/vrypan/bucket3 . Auf meiner Website http://bc3.brite.biz/ kann ein chinesischer Beitrag erfolgreich veröffentlicht werden.
python
python-2.7
chinese-locale
Fischer
quelle
quelle
Antworten:
tl; dr / schnelle Lösung
reload
Hacks zu verwendenUnicode Zen in Python 2.x - Die lange Version
Ohne die Quelle zu sehen, ist es schwierig, die Grundursache zu kennen, daher muss ich allgemein sprechen.
UnicodeDecodeError: 'ascii' codec can't decode byte
Dies geschieht im Allgemeinen, wenn Sie versuchen, eine Python 2.x-Dateistr
, die kein ASCII enthält, in eine Unicode-Zeichenfolge zu konvertieren, ohne die Codierung der ursprünglichen Zeichenfolge anzugeben.Kurz gesagt, Unicode-Zeichenfolgen sind ein völlig separater Typ von Python-Zeichenfolgen, der keine Codierung enthält. Sie enthalten nur Unicode- Punktcodes und können daher jeden Unicode-Punkt aus dem gesamten Spektrum enthalten. Zeichenfolgen enthalten codierten Text, zB UTF-8, UTF-16, ISO-8895-1, GBK, Big5 usw. Zeichenfolgen werden in Unicode dekodiert und Unicodes werden in Zeichenfolgen codiert . Dateien und Textdaten werden immer in codierten Zeichenfolgen übertragen.
Die Autoren des Markdown-Moduls verwenden wahrscheinlich
unicode()
(wo die Ausnahme ausgelöst wird) als Qualitätsgatter für den Rest des Codes - es konvertiert ASCII oder umschließt vorhandene Unicodes-Zeichenfolgen erneut in eine neue Unicode-Zeichenfolge. Die Markdown-Autoren können die Codierung der eingehenden Zeichenfolge nicht kennen. Sie müssen daher Zeichenfolgen in Unicode-Zeichenfolgen dekodieren, bevor Sie sie an Markdown übergeben.Unicode-Zeichenfolgen können in Ihrem Code mit dem
u
Präfix für Zeichenfolgen deklariert werden . Z.BUnicode-Zeichenfolgen können auch aus Dateien, Datenbanken und Netzwerkmodulen stammen. In diesem Fall müssen Sie sich keine Gedanken über die Codierung machen.
Fallstricke
Die Konvertierung von
str
in Unicode kann auch dann erfolgen, wenn Sie nicht explizit aufrufenunicode()
.Die folgenden Szenarien verursachen
UnicodeDecodeError
Ausnahmen:Beispiele
In der folgenden Abbildung sehen Sie, wie das Wort
café
je nach Terminaltyp entweder in "UTF-8" - oder "Cp1252" -Codierung codiert wurde. In beiden Beispielencaf
ist nur reguläres ASCII. In UTF-8é
wird mit zwei Bytes codiert. In "Cp1252" ist é 0xE9 (was auch der Unicode-Punktwert ist (es ist kein Zufall)). Das Richtigedecode()
wird aufgerufen und die Konvertierung in einen Python-Unicode ist erfolgreich:In diesem Diagramm
decode()
wird mit aufgerufenascii
(was dem Aufrufenunicode()
ohne angegebene Codierung entspricht). Da ASCII keine Bytes größer als enthalten kann0x7F
, wird eineUnicodeDecodeError
Ausnahme ausgelöst:Das Unicode-Sandwich
Es wird empfohlen, in Ihrem Code ein Unicode-Sandwich zu erstellen, in dem Sie alle eingehenden Daten in Unicode-Zeichenfolgen dekodieren, mit Unicodes arbeiten und
str
auf dem Weg nach draußen in s codieren . Dies erspart Ihnen die Sorge um die Codierung von Zeichenfolgen in der Mitte Ihres Codes.Eingabe / Dekodierung
Quellcode
Wenn Sie Nicht-ASCII in Ihren Quellcode backen müssen, erstellen Sie einfach Unicode-Zeichenfolgen, indem Sie der Zeichenfolge ein Präfix voranstellen
u
. Z.BDamit Python Ihren Quellcode dekodieren kann, müssen Sie einen Codierungsheader hinzufügen, der der tatsächlichen Codierung Ihrer Datei entspricht. Wenn Ihre Datei beispielsweise als 'UTF-8' codiert wäre, würden Sie Folgendes verwenden:
Dies ist nur erforderlich, wenn Ihr Quellcode Nicht-ASCII enthält .
Dateien
Normalerweise werden Nicht-ASCII-Daten aus einer Datei empfangen. Das
io
Modul bietet einen TextWrapper, der Ihre Datei im laufenden Betrieb unter Verwendung eines bestimmten Codes dekodiertencoding
. Sie müssen die richtige Codierung für die Datei verwenden - dies kann nicht leicht erraten werden. Zum Beispiel für eine UTF-8-Datei:my_unicode_string
wäre dann für die Weitergabe an Markdown geeignet. Wenn aUnicodeDecodeError
aus derread()
Zeile stammt, haben Sie wahrscheinlich den falschen Codierungswert verwendet.CSV-Dateien
Das Python 2.7 CSV-Modul unterstützt keine Nicht-ASCII-Zeichen 😩. Hilfe erhalten Sie jedoch unter https://pypi.python.org/pypi/backports.csv .
Verwenden Sie es wie oben, aber übergeben Sie die geöffnete Datei daran:
Datenbanken
Die meisten Python-Datenbanktreiber können Daten in Unicode zurückgeben, erfordern jedoch normalerweise eine kleine Konfiguration. Verwenden Sie für SQL-Abfragen immer Unicode-Zeichenfolgen.
MySQLFügen Sie in der Verbindungszeichenfolge Folgendes hinzu:
Z.B
PostgreSQLHinzufügen:
HTTP
Webseiten können in nahezu jeder Codierung codiert werden. Der
Content-type
Header sollte eincharset
Feld enthalten , das auf die Codierung hinweist. Der Inhalt kann dann manuell gegen diesen Wert dekodiert werden. Alternativ gibt Python-Requests Unicodes in zurückresponse.text
.Manuell
Wenn Sie Zeichenfolgen manuell dekodieren müssen, können Sie einfach tun
my_string.decode(encoding)
, woencoding
die entsprechende Codierung ist. Von Python 2.x unterstützte Codecs finden Sie hier: Standardcodierungen . Wenn Sie erhalten, habenUnicodeDecodeError
Sie wahrscheinlich die falsche Codierung.Das Fleisch des Sandwichs
Arbeiten Sie mit Unicodes wie mit normalen Strs.
Ausgabe
Standardausgabe / Drucken
print
schreibt durch den stdout-Stream. Python versucht, einen Encoder auf stdout so zu konfigurieren, dass Unicodes mit der Codierung der Konsole codiert werden. Wenn es sich beispielsweise um eine Linux-Shelllocale
handelten_GB.UTF-8
, wird die Ausgabe in codiertUTF-8
. Unter Windows sind Sie auf eine 8-Bit-Codepage beschränkt.Eine falsch konfigurierte Konsole, z. B. ein beschädigtes Gebietsschema, kann zu unerwarteten Druckfehlern führen.
PYTHONIOENCODING
Umgebungsvariable kann die Codierung für stdout erzwingen.Dateien
io.open
Kann genau wie die Eingabe verwendet werden, um Unicodes transparent in codierte Byte-Zeichenfolgen zu konvertieren.Datenbank
Mit derselben Konfiguration zum Lesen können Unicodes direkt geschrieben werden.
Python 3
Python 3 ist nicht mehr Unicode-fähig als Python 2.x, ist jedoch in Bezug auf das Thema etwas weniger verwirrt. ZB ist der reguläre
str
jetzt ein Unicode-String und der altestr
jetztbytes
.Die Standardcodierung ist UTF-8. Wenn Sie also
.decode()
eine Byte-Zeichenfolge ohne Angabe einer Codierung verwenden, verwendet Python 3 die UTF-8-Codierung. Dies behebt wahrscheinlich 50% der Unicode-Probleme.Arbeitet außerdem
open()
standardmäßig im Textmodus, gibt also dekodiertestr
(Unicode- Rückgaben ) zurück. Die Codierung wird von Ihrem Gebietsschema abgeleitet, das auf Un * x-Systemen in der Regel UTF-8 oder auf Windows-Boxen eine 8-Bit-Codepage wie Windows-1251 ist.Warum sollten Sie nicht verwenden
sys.setdefaultencoding('utf8')
Es ist ein böser Hack (es gibt einen Grund, den Sie verwenden müssen
reload
), der nur Probleme maskiert und Ihre Migration zu Python 3.x behindert. Verstehen Sie das Problem, beheben Sie die Grundursache und genießen Sie Unicode Zen. Siehe Warum sollten wir sys.setdefaultencoding ("utf-8") NICHT in einem py-Skript verwenden? für weitere Detailsquelle
io.open
zum Lesen / Schreiben von Dateien, verwenden Siefrom __future__ import unicode_literals
andere Dateneingaben / -ausgaben (z. B. Datenbanken), um Unicode zu verwenden.PYTHONIOENCODING=utf-8
. Wenn dies das Problem nicht behebt, müssen Sie sich an den Autor des Skripts wenden, um dessen Code zu beheben.Endlich hab ich es:
Lass mich das überprüfen:
Das Obige zeigt die Standardcodierung von Python
utf8
. Dann ist der Fehler nicht mehr.quelle
str
, sodass sie dort nicht überfällig ist. In Python 2.x befand sich Unicode im Übergangszustand, daher wäre es gefährlich gewesen, beim Konvertieren von Bytes in Unicodes eine Codierung anzunehmen. Daher war die Standardcodierung von ASCII für Py2 eine bewusste Wahl, und warum das Ändern der Standardcodierung das absichtliche erneute Laden erfordertsys
. Der richtige Weg, um Codierungsfehler in Py2 zu verbannen, besteht darin, Zeichenfolgen eindeutig zu dekodieren und in Unicode zu codieren, wenn Konvertierungen erforderlich sind - und nicht nur davon auszugehen, dass Zeichenfolgen UTF-8-codiert sind.Dies ist das klassische "Unicode-Problem". Ich glaube, dass das Erklären dies über den Rahmen einer StackOverflow-Antwort hinausgeht, um vollständig zu erklären, was passiert.
Es ist gut erklärt hier .
In einer sehr kurzen Zusammenfassung haben Sie etwas, das als Zeichenfolge von Bytes interpretiert wird, an etwas übergeben, das es in Unicode-Zeichen dekodieren muss, aber der Standardcodec (ASCII) schlägt fehl.
Die Präsentation, auf die ich Sie hingewiesen habe, gibt Ratschläge, um dies zu vermeiden. Machen Sie Ihren Code zu einem "Unicode-Sandwich". In Python 2
from __future__ import unicode_literals
hilft die Verwendung von .Update: Wie kann der Code repariert werden:
OK - in Ihrer Variablen "Quelle" haben Sie einige Bytes. Aus Ihrer Frage geht nicht hervor, wie sie dort hineingekommen sind - vielleicht haben Sie sie aus einem Webformular gelesen? In jedem Fall sind sie nicht mit ASCII codiert, aber Python versucht, sie in Unicode zu konvertieren, vorausgesetzt, sie sind es. Sie müssen explizit angeben, wie die Codierung lautet. Dies bedeutet, dass Sie wissen müssen , wie die Codierung lautet! Das ist nicht immer einfach und hängt ganz davon ab, woher diese Saite stammt. Sie könnten mit einigen gängigen Codierungen experimentieren - zum Beispiel UTF-8. Sie teilen unicode () die Codierung als zweiten Parameter mit:
quelle
currentFile = open(filename, 'rt', encoding='latin1')
odercurrentFile = open(filename, 'rt', encoding='utf-8')
- siehe hier: stackoverflow.com/a/23917799/2047442In einigen Fällen wird beim Überprüfen Ihrer Standardcodierung (
print sys.getdefaultencoding()
) zurückgegeben, dass Sie ASCII verwenden. Wenn Sie zu UTF-8 wechseln, funktioniert dies je nach Inhalt Ihrer Variablen nicht. Ich habe einen anderen Weg gefunden:quelle
reload(sys)
wird aus diesem besonderen Grund verwendet.Ich habe nach der folgenden Fehlermeldung gesucht:
Ich habe es endlich behoben, indem ich 'Kodierung' angegeben habe:
Ich wünschte, es könnte dir auch helfen.
quelle
Ursache für diesen Fehler: input_string muss Unicode sein, aber str wurde angegeben
Ursache für diesen Fehler: Versuch, Unicode input_string in Unicode zu konvertieren
Überprüfen Sie also zuerst, ob Ihr input_string ist,
str
und konvertieren Sie ihn gegebenenfalls in Unicode:Zweitens ändert das Obige nur den Typ, entfernt jedoch keine Nicht-ASCII-Zeichen. Wenn Sie Nicht-ASCII-Zeichen entfernen möchten:
quelle
Ich finde, das Beste ist, immer in Unicode zu konvertieren - aber das ist schwierig zu erreichen, da Sie in der Praxis jedes Argument überprüfen und in jede Funktion und Methode konvertieren müssen, die Sie jemals geschrieben haben und die eine Form der Zeichenfolgenverarbeitung enthält.
Daher habe ich den folgenden Ansatz entwickelt, um entweder Unicodes oder Byte-Strings von beiden Eingaben zu garantieren. Kurz gesagt, schließen Sie die folgenden Lambdas ein und verwenden Sie sie :
Beispiele:
Hier sind einige weitere Gründe dafür .
quelle
print unicode(u'Zürich', encoding="UTF-8")
und dann beschweren Sie sich "Aber erstaunlicherweise können Sie Unicode ext nicht in UTF8 codieren".unicode()
codiert nicht; es dekodiert und Sie können keinen Unicode dekodieren - es ist bereits dekodiert!Überprüfen Sie Folgendes, um dies auf Betriebssystemebene in einer Ubuntu-Installation zu beheben:
Wenn du bekommst
anstatt
dann setzen
LC_CTYPE
undLC_ALL
so:quelle
Encode konvertiert ein Unicode-Objekt in ein String-Objekt. Ich denke, Sie versuchen, ein String-Objekt zu codieren. Konvertieren Sie zuerst Ihr Ergebnis in ein Unicode-Objekt und codieren Sie dieses Unicode-Objekt dann in 'utf-8'. zum Beispiel
quelle
Ich hatte das gleiche Problem, aber es funktionierte nicht für Python 3. Ich folgte diesem und es löste mein Problem:
Sie müssen die Codierung festlegen, wenn Sie die Datei lesen / schreiben.
quelle
Habe den gleichen Fehler und dies hat meinen Fehler behoben. Vielen Dank! Python 2 und Python 3, die sich in der Unicode-Behandlung unterscheiden, machen eingelegte Dateien zum Laden ziemlich inkompatibel. Verwenden Sie also das Codierungsargument von Python Pickle. Der folgende Link hat mir geholfen, das ähnliche Problem zu lösen, als ich versuchte, eingelegte Daten aus meinem Python 3.7 zu öffnen, während meine Datei ursprünglich in der Python 2.x-Version gespeichert wurde. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Ich kopiere die Funktion load_pickle in mein Skript und rufe beim Laden von load_pickle (pickle_file) auf Eingabedaten wie folgt:
Die Funktion load_pickle ist hier:
quelle
load_pickle
Funktion in Ihre Antwort aufzunehmen.Das hat bei mir funktioniert:
quelle
Kurz gesagt, um eine ordnungsgemäße Unicode-Behandlung in Python 2 sicherzustellen:
io.open
zum Lesen / Schreiben von Dateienfrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Erläuterungen finden Sie in der ausführlichen Antwort von @Alastair McCormack .
quelle
io.open(path, 'r', encoding='utf-8')
Sie diese Option, um utf-8-codierte Dateien zu lesen.Ich hatte den gleichen Fehler mit URLs, die Nicht-ASCII-Zeichen (Bytes mit Werten> 128) enthielten. Meine Lösung:
Hinweis: utf-8, utf8 sind einfach Aliase. Die Verwendung von nur 'utf8' oder 'utf-8' sollte auf die gleiche Weise funktionieren
In meinem Fall, der für mich in Python 2.7 funktioniert hat, hat diese Zuweisung vermutlich 'etwas' in der
str
internen Darstellung geändert - dh sie erzwingt die richtige Dekodierung der gesicherten Bytesequenz inurl
und setzt den String schließlich in ein utf-8str
mit all die Magie am richtigen Ort. Unicode in Python ist für mich schwarze Magie. Hoffe nützlichquelle
Ich habe das gleiche Problem mit der Saite "PastelerÃa Mallorca" und habe gelöst mit:
quelle
In einem Django (1.9.10) / Python 2.7.5-Projekt habe ich häufige
`UnicodeDecodeError
Ausnahmen; hauptsächlich, wenn ich versuche, Unicode-Zeichenfolgen in die Protokollierung einzugeben. Ich habe eine Hilfsfunktion für beliebige Objekte erstellt, um sie im Grunde genommen auf 8-Bit-ASCII-Zeichenfolgen zu formatieren und alle Zeichen, die nicht in der Tabelle enthalten sind, durch '?' Zu ersetzen. Ich denke, es ist nicht die beste Lösung, aber da die Standardcodierung ASCII ist (und ich sie nicht ändern möchte), reicht es aus:quelle
Dieser Fehler tritt auf, wenn unsere Zeichenfolge einige Nicht-ASCII-Zeichen enthält und wir Operationen an dieser Zeichenfolge ohne ordnungsgemäße Dekodierung ausführen. Dies hat mir geholfen, mein Problem zu lösen. Ich lese eine CSV-Datei mit Spalten-ID, Text und Dekodierungszeichen wie folgt:
quelle
Hier ist meine Lösung, fügen Sie einfach die Codierung hinzu.
with open(file, encoding='utf8') as f
Und da das Lesen der Handschuhdatei lange dauern wird, empfehle ich, die Handschuhdatei in eine Numpy-Datei umzuwandeln. Wenn Sie die Einbettungsgewichte netx time lesen, sparen Sie Zeit.
Hauptlink: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
quelle
Geben Sie Folgendes an: # encoding = utf-8 oben in Ihrer Python-Datei. Das Problem sollte behoben sein
quelle