UnicodeDecodeError: Der Codec 'ascii' kann das Byte 0xef an Position 1 nicht dekodieren

106

Ich habe einige Probleme beim Versuch, eine Zeichenfolge in UTF-8 zu codieren. Ich habe zahlreiche Dinge ausprobiert, einschließlich der Verwendung von string.encode('utf-8')und unicode(string), aber ich erhalte den Fehler:

UnicodeDecodeError: Der Codec 'ascii' kann das Byte 0xef an Position 1 nicht dekodieren: Ordnungszahl nicht im Bereich (128)

Das ist meine Zeichenfolge:

(。・ω・。)ノ

Ich sehe nicht, was falsch läuft, eine Idee?

Bearbeiten: Das Problem ist, dass das Drucken der Zeichenfolge so wie sie ist nicht richtig angezeigt wird. Auch dieser Fehler, wenn ich versuche, es zu konvertieren:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
Markum
quelle
Es ist nur eine normal eingefügte Zeichenfolge. Das gleiche passiert, wenn ich nur versuche, es zu drucken.
Markum
Ich treffe das gleiche bei der Pip-Installation und behebe es von hier aus: [installiere etwas] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Antworten:

70

Dies hängt damit zusammen, dass die Codierung Ihres Terminals nicht auf UTF-8 eingestellt ist. Hier ist mein Terminal

$ echo $LANG
en_GB.UTF-8
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> 

Auf meinem Terminal funktioniert das Beispiel mit dem oben genannten, aber wenn ich die LANGEinstellung los werde, funktioniert es nicht

$ unset LANG
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
>>> 

Konsultieren Sie die Dokumente für Ihre Linux-Variante, um herauszufinden, wie Sie diese Änderung dauerhaft vornehmen können.

Nick Craig-Wood
quelle
1
Fehlende Gebietsschemas könnten ebenfalls ein Grund sein. Um sie zu installieren, führen Sie sudo apt-get install language-pack-deoder sudo locale-gen de_DE.UTF-8(für deutsche Ländereinstellungen) aus.
Nicht
Für mich ist die fehlende Umgebungsvariable LC_ALLund der einfachste Wert, der sie beheben würde, istC.UTF-8
Robin Winslow,
24

Versuchen:

string.decode('utf-8')  # or:
unicode(string, 'utf-8')

bearbeiten:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')gibt u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', was richtig ist.

Ihr Problem muss sich also an einem anderen Ort befinden, möglicherweise wenn Sie versuchen, etwas damit zu tun, wenn eine implizite Konvertierung stattfindet (könnte Drucken, Schreiben in einen Stream sein ...)

Um mehr zu sagen, müssen wir Code sehen.

mata
quelle
Beide kehren zurückUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Markum
'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Markum
1
Ich versuche nur, die Originalzeichenfolge im Originalformat zu drucken, aber ich verstehe (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum
4
das stringist utf8-codiert. Wenn Sie es drucken, werden nur die Bytes mit dem Ausgabestream verbunden, und wenn Ihr Terminal es nicht als utf8 interpretiert, entsteht Müll. mit decodeSie es in Unicode konvertieren, dann können Sie encodees wieder eine Codierung Terminal versteht.
Mata
21

Mein +1 zum Kommentar von mata unter https://stackoverflow.com/a/10561979/1346705 und zur Demonstration von Nick Craig-Wood. Sie haben die Zeichenfolge korrekt dekodiert. Das Problem liegt beim printBefehl, da er die Unicode-Zeichenfolge in die Konsolencodierung konvertiert und die Konsole die Zeichenfolge nicht anzeigen kann. Versuchen Sie, die Zeichenfolge in eine Datei zu schreiben, und sehen Sie sich das Ergebnis mit einem anständigen Editor an, der Unicode unterstützt:

import codecs

s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()

Dann wirst du sehen (。・ω・。)ノ.

pepr
quelle
10

Wenn Sie auf einem Remote- Host arbeiten, schauen Sie /etc/ssh/ssh_configauf Ihrem lokalen PC nach.

Wenn diese Datei eine Zeile enthält:

SendEnv LANG LC_*

Kommentieren Sie es mit dem Hinzufügen #am Anfang der Zeile aus. Es könnte helfen.

sshSendet mit dieser Zeile sprachbezogene Umgebungsvariablen Ihres PCs an den Remote- Host. Es verursacht viele Probleme.

Tsutomu
quelle
Vielen Dank! Diese lösten das Problem, dass ich Pip-Pakete mit Ansible und Vagrant installiert hatte
Maritza Esparza
10

Versuchen Sie, die Systemstandardcodierung wie utf-8zu Beginn des Skripts festzulegen, damit alle Zeichenfolgen damit codiert werden.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Andrei Krasutski
quelle
Warum brauchen wir in diesem Fall das Nachladen?
fallender Hund
Dies funktioniert in Python 3 nicht, wie hier erläutert . Für mich hat Tsutomus Antwort unten den Trick getan.
Piyush Goel
5

Es ist in Ordnung, den folgenden Code oben in Ihrem Skript zu verwenden, wie Andrei Krasutski vorgeschlagen hat.

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Ich werde Ihnen jedoch vorschlagen, # -*- coding: utf-8 -*ganz oben im Skript eine Zeile hinzuzufügen .

Wenn ich es weglasse, wird in meinem Fall der folgende Fehler ausgegeben, wenn ich versuche, ihn auszuführen basic.py.

$ python basic.py
  File "01_basic.py", line 14
SyntaxError: Non-ASCII character '\xd9' in file basic.py on line 14, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Das Folgende ist der vorhandene Code, basic.pyder den obigen Fehler auslöst.

Code mit Fehler

from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Dann habe ich # -*- coding: utf-8 -*-ganz oben eine Zeile hinzugefügt und ausgeführt. Es funktionierte.

Code ohne Fehler

# -*- coding: utf-8 -*-
from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Vielen Dank.

Hygull
quelle
1
Mit #coding: utf-8anstatt # -*- coding: utf-8 -*- dies ist leichter zu merken. Funktioniert sofort mit Python PEP 263 - Definieren von Python-Quellcode-Codierungen .
Andrei Krasutski
Danke für den Vorschlag. Werde es an meinem Ende ausprobieren und es in der Antwort aktualisieren.
Hygull
4

Keine Probleme mit meinem Terminal. Die obigen Antworten haben mir geholfen, in die richtigen Richtungen zu schauen, aber es hat bei mir nicht funktioniert, bis ich hinzugefügt habe 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore')

Wie im Kommentar unten angegeben, kann dies zu unerwünschten Ergebnissen führen. OTOH, es kann auch gerade gut genug sein, um die Dinge zum Laufen zu bringen, und es ist Ihnen egal, ob Sie einige Charaktere verlieren.

kqw
quelle
2
Dies ist falsch. Sie zwingen Ihre Lambda-Codierungsfunktion, die Codierung selbst zu ignorieren, was bedeutet, dass Sie Zeichen verlieren.
Maximiliano Rios
2
Dies löste mein Problem, bei dem ich die ursprüngliche Codierung nicht kannte und es mir egal war, einige Zeichen zu verlieren.
Edhowler
2

Dies funktioniert für Ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
wlredeye
quelle
1

Es sieht so aus, als ob Ihre Zeichenfolge codiert utf-8ist. Was genau ist das Problem? Oder was versuchst du hier zu machen ..?

Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'
wim
quelle
Wenn Sie die Originalzeichenfolge so drucken, wie sie ist (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, möchte ich, dass sie ordnungsgemäß codiert wird.
Markum
1

In meinem Fall wurde dies dadurch verursacht, dass meine Unicode-Datei mit einer "Stückliste" gespeichert wurde. Um dies zu lösen, habe ich die Datei mit BBEdit aufgebrochen und "Speichern unter ..." ausgewählt, um "Unicode (UTF-8)" zu codieren, und nicht "Unicode (UTF-8, mit Stückliste)". ""

user336828
quelle
0

Ich habe den gleichen Fehlertyp erhalten und festgestellt, dass die Konsole die Zeichenfolge nicht in einer anderen Sprache anzeigen kann. Daher habe ich die folgenden Codeänderungen vorgenommen, um default_charset als UTF-8 festzulegen.

data_head = [('\x81\xa1\x8fo\x89\xef\x82\xa2\x95\xdb\x8f\xd8\x90\xa7\x93x\x81\xcb3\x8c\x8e\x8cp\x91\xb1\x92\x86(\x81\x86\x81\xde\x81\x85)\x81\xa1\x8f\x89\x89\xf1\x88\xc8\x8aO\x81A\x82\xa8\x8b\xe0\x82\xcc\x90S\x94z\x82\xcd\x88\xea\x90\xd8\x95s\x97v\x81\xa1\x83}\x83b\x83v\x82\xcc\x82\xa8\x8e\x8e\x82\xb5\x95\xdb\x8c\xaf\x82\xc5\x8fo\x89\xef\x82\xa2\x8am\x92\xe8\x81\xa1', 'shift_jis')]
default_charset = 'UTF-8' #can also try 'ascii' or other unicode type
print ''.join([ unicode(lin[0], lin[1] or default_charset) for lin in data_head ])
Azam Khan
quelle
-1

Stückliste, es ist so oft Stückliste für mich

vi die Datei verwenden

:set nobomb

und speichern Sie es. Das behebt es in meinem Fall fast immer

Olly W.
quelle
-1

Ich hatte den gleichen Fehler mit URLs, die Nicht-ASCII-Zeichen enthielten (Bytes mit Werten> 128).

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

In Python 2.7 hat diese Zuweisung für mich funktioniert und ich nehme an, dass diese Zuweisung 'etwas' in der strinternen Darstellung geändert hat - dh sie erzwingt die richtige Dekodierung der gesicherten Bytesequenz in urlund setzt den String schließlich in eine utf-8 str mit all der Magie in der richtige Ort. Unicode in Python ist für mich schwarze Magie. Hoffe nützlich

Fabiano Tarlao
quelle
-2

Ich löse das Problem, das sich in der Datei settings.py mit 'ENGINE': 'django.db.backends.mysql' ändert. Verwenden Sie nicht 'ENGINE': 'mysql.connector.django',

user3787102
quelle
@rayryeng Könnten Sie den Grund für Ihre Bearbeitung erklären? Es scheint die Bedeutung dessen, was das OP geschrieben hat, vollständig zu ändern, von der Empfehlung einer bestimmten Einstellung bis zur Empfehlung dagegen .
niemand
@ AndrewMedico - Ich entschuldige mich. Ich habe gesehen, dass dieser Beitrag einem anderen sehr ähnlich ist, also habe ich geglaubt, dass sie gleich sind. Ich werde zurückkehren.
Rayryeng
-2

Konvertieren Sie den Text einfach explizit in einen String mit str(). Hat für mich gearbeitet.

Supratim Samantray
quelle