2009-11-19 15 views
7

ich diesen Fehler:Python, UnicodeDecodeError

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128) 

habe ich versucht, viele verschiedene Codecs Einstellung (in der Kopfzeile, wie # -*- coding: utf8 -*-) oder sogar mit u "string", aber es scheint immer noch.

Wie behebe ich das?

Edit: Ich weiß nicht, den tatsächlichen Charakter, die dies verursacht, aber da dies ein Programm, den Ordner rekursiv durchsucht, es muss eine Datei mit seltsamen Zeichen im Namen

-Code gefunden hat:

# -*- coding: utf8 -*- 


# by TerabyteST 

########################### 

# Explores given path recursively 
# and finds file which size is bigger than the set treshold 

import sys 
import os 

class Explore(): 
    def __init__(self): 
     self._filelist = [] 

    def exploreRec(self, folder, treshold): 
     print folder 
     generator = os.walk(folder + "/") 
     try: 
      content = generator.next() 
     except: 
      return 
     folders = content[1] 
     files = content[2] 
     for n in folders: 
      if "$" in n: 
       folders.remove(n) 
     for f in folders: 
      self.exploreRec(u"%s/%s"%(folder, f), treshold) 
     for f in files: 
      try: 
       rawsize = os.path.getsize(u"%s/%s"%(folder, f)) 
      except: 
       print "Error reading file %s"%u"%s/%s"%(folder, f) 
       continue 
      mbsize = rawsize/(1024 * 1024.0) 
      if mbsize >= treshold: 
       print "File %s is %d MBs!"%(u"%s/%s"%(folder, f), mbsize) 

Fehler:

Traceback (most recent call last): 
    File "<pyshell#19>", line 1, in <module> 
    a.exploreRec("C:", 100) 
    File "D:/Python/Explorator/shitfinder.py", line 35, in exploreRec 
    print "Error reading file %s"%u"%s/%s"%(folder, f) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128) 

Hier ist, was mit gezeigt wird print repr("Error reading file %s"%u"%s/%s"%(folder.decode('utf-8','ignore'), f.decode('utf-8','ignore')))

>>> a = Explore() 
>>> a.exploreRec("C:", 100) 
File C:/Program Files/Ableton/Live 8.0.4/Resources/DefaultPackages/Live8Library_v8.2.alp is 258 MBs! 
File C:/Program Files/Adobe/Reader 9.0/Setup Files/{AC76BA86-7AD7-1040-7B44-A90000000001}/Data1.cab is 114 MBs! 
File C:/Program Files/Microsoft Games/Age of Empires III/art/Art1.bar is 393 MBs! 
File C:/Program Files/Microsoft Games/Age of Empires III/art/art2.bar is 396 MBs! 
File C:/Program Files/Microsoft Games/Age of Empires III/art/art3.bar is 228 MBs! 
File C:/Program Files/Microsoft Games/Age of Empires III/Sound/Sound.bar is 273 MBs! 
File C:/ProgramData/Microsoft/Search/Data/Applications/Windows/Windows.edb is 162 MBs! 
REPR: 
u"Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/0/Sito web di Mirror's Edge.lnk" 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/0/Sito web di Mirror's Edge.lnk 
REPR: 
u"Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/1/Contenuti scaricabili di Mirror's Edge.lnk" 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/1/Contenuti scaricabili di Mirror's Edge.lnk 
REPR: 
u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Google Talk/Supporto/Modalitiagnostica di Google Talk.lnk' 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Google Talk/Supporto/Modalitiagnostica di Google Talk.lnk 
REPR: 
u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Microsoft SQL Server 2008/Strumenti di configurazione/Segnalazione errori e utilizzo funzionaliti SQL Server.lnk' 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Microsoft SQL Server 2008/Strumenti di configurazione/Segnalazione errori e utilizzo funzionaliti SQL Server.lnk 
REPR: 
u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox/Mozilla Firefox (Modalitrovvisoria).lnk' 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox/Mozilla Firefox (Modalitrovvisoria).lnk 
REPR: 
u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox 3.6 Beta 1/Mozilla Firefox 3.6 Beta 1 (Modalitrovvisoria).lnk' 
END REPR: 
Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox 3.6 Beta 1/Mozilla Firefox 3.6 Beta 1 (Modalitrovvisoria).lnk 

Traceback (most recent call last): 
    File "<pyshell#21>", line 1, in <module> 
    a.exploreRec("C:", 100) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
    File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec 
    self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x99 in position 78: ordinal not in range(128) 
>>> 
+3

Kein Code, keine Hilfe! –

+0

Ein vollständiger Traceback würde auch helfen. – retracile

+0

@John: Nicht ganz richtig. Der "coding: utf-8" -Kommentar am Anfang legt fest, welche Quelldatei encoding python erwartet. –

Antwort

13

Wir können nicht erraten, was Sie zu tun versuchen, noch was in Ihrem Code, nicht das, was „-Einstellung viele verschiedene Codecs "bedeutet, noch was du" String "für dich tun soll.

Bitte ändern Sie Ihren Code in den Ausgangszustand, damit er möglichst gut wiedergibt, führen Sie ihn erneut aus und bearbeiten Sie dann Ihre Frage, um (1) die vollständige Traceback- und Fehlermeldung zu erhalten (2) Snippet, das die letzte Anweisung in Ihrem Skript enthält, die im Traceback (3) erscheint, eine kurze Beschreibung dessen, was der Code tun soll (4), welche Version von Python Sie gerade ausführen.

bearbeiten nach Details zu Frage hinzugefügt:

(0) Lassen Sie uns auf die fehlerhafte Anweisung einige Transformationen versuchen:

Original:
print "Error reading file %s"%u"%s/%s"%(folder, f)
In Räume für reduzierte Unlesbarkeit:
print "Error reading file %s" % u"%s/%s" % (folder, f)
Fügen Sie Klammern hinzu, um die Bewertungsreihenfolge zu betonen:
print ("Error reading file %s" % u"%s/%s") % (folder, f)
Bewerten Sie den (konstant) Ausdruck in Klammern:
print u"Error reading file %s/%s" % (folder, f)

Ist das wirklich, was Sie wollen? Vorschlag: konstruiere den Weg ONCE mit einer besseren Methode (siehe Punkt (2) unten).

(1) Verwenden Sie im Allgemeinen repr(foo) oder "%r" % foo für die Diagnose. Auf diese Weise ist es weniger wahrscheinlich, dass Ihr Diagnosecode eine Ausnahme verursacht (wie hier) und Sie vermeiden Mehrdeutigkeiten. Fügen Sie die Anweisung print repr(folder), repr(f) ein, bevor Sie versuchen, die Größe abzurufen, erneut auszuführen und einen Bericht zu erstellen.

(2) Zwing Pfade nicht durch u"%s/%s" % (folder, filename) ... verwenden os.path.join(folder, filename)

(3) nicht kahl excepts haben, für bekannte Probleme überprüfen. So dass unbekannte Probleme so etwas wie diese nicht unbekannt bleiben, tun:

try: 
    some_code() 
except ReasonForBaleOutError: 
    continue 
except: 
    # something's gone wrong, so get diagnostic info 
    print repr(interesting_datum_1), repr(interesting_datum_2) 
    # ... and get traceback and error message 
    raise 

Eine anspruchsvollere Art und Weise statt Druck bedeuten würde Anmeldung, aber die oben ist viel besser, als nicht zu wissen, was los ist.

Weitere Änderungen nach rtm ("os.walk"), alten Legenden zu erinnern, und Re-Lektüre Code:

(4) os.walk() geht über den ganzen Baum; Sie müssen es nicht rekursiv aufrufen.

(5) Wenn Sie eine Unicode-Zeichenfolge an os.walk() übergeben, werden die Ergebnisse (Pfade, Dateinamen) als Unicode gemeldet. Du brauchst nicht all das "blah" Zeug. Dann müssen Sie nur auswählen, wie Sie die Unicode-Ergebnisse anzeigen.

(6) Entfernen von Pfaden mit "$" in ihnen: Sie müssen die Liste in situ ändern, aber Ihre Methode ist gefährlich. Probieren Sie etwas wie folgt aus:

for i in xrange(len(folders), -1, -1): 
    if '$' in folders[i]: 
     del folders[i] 

(7) Ihr beziehen sich auf Dateien durch einen Ordnernamen verbinden und einen Dateinamen. Sie verwenden den Ordnernamen ORIGINAL. Wenn Sie die Rekursion herausreißen, wird dies nicht funktionieren. Sie müssen den aktuell verworfenen Wert content[0] von os.walk verwenden.

(8) Sie sollten sich etwas finden, sehr einfach wie mit:

for folder, subfolders, filenames in os.walk(unicoded_top_folder): 

Es gibt keine Notwendigkeit für generator = os.walk(...); try: content = generator.next() etc und BTW, wenn Sie jemals generator.next() in Zukunft tun müssen, verwenden Sie except StopIteration statt einer bloßen Ausnahme .

(9) Wenn der Aufrufer einen nicht vorhandenen Ordner zur Verfügung stellt, wird keine Ausnahme ausgelöst, es tut nichts. Wenn der angegebene Ordner existiert, aber leer ist, dito. Wenn Sie zwischen diesen beiden Szenarien unterscheiden müssen, müssen Sie selbst zusätzliche Tests durchführen.

Antwort auf diesen Kommentar aus dem OP: "" "Danke, bitte lesen Sie die Informationen repr() hat im ersten Beitrag gezeigt. Ich weiß nicht, warum es so viele verschiedene Artikel gedruckt, aber es aussieht sie alle haben Probleme und die Gemeinsamkeit zwischen allen ist, dass sie .ink-Dateien sind. Kann das das Problem sein? Auch in den letzten, den firefox, druckt es (Modalitrovvisoria), während der echte Dateiname aus dem Explorer enthält (Modalità provvisoria)

(10) Das ist nicht ".INK" .lower(), es ist ".LNK" .lower() ... vielleicht musst du die Schriftart ändern, egal was du bist das mit lesen.

(11) Die Tatsache, dass die "Problem" -Dateinamen alle in ".lnk" enden, kann etwas damit zu tun haben, dass os.walk() und/oder Windows etwas mit den Namen dieser Dateien machen.

(12) wiederhole ich hier die Python-Anweisung, die Sie die Ausgabe zu produzieren verwendet werden, um mit einigen Leerzeichen eingeführt:

print repr(
    "Error reading file %s" \ 
    % u"%s/%s" % (
     folder.decode('utf-8','ignore'), 
     f.decode('utf-8','ignore') 
     ) 
    ) 

Es scheint, dass Sie nicht gelesen haben, oder nicht verstanden, oder einfach nur ignoriert, die Beratung, die ich Ihnen in einem Kommentar zu einer anderen Antwort (und der Antwort des Beantworters) gegeben habe: UTF-8 ist NICHT relevant im Zusammenhang mit Dateinamen in einem Windows-Dateisystem.

Uns interessiert, in welcher Ordner und f verweisen. Sie haben alle Beweise zertrampelt, indem Sie versucht haben, UTF-8 zu entschlüsseln. Sie haben die Verschleierung durch Verwendung der Option "Ignorieren" verstärkt. Hätten Sie die Option "replace" verwendet, hätten Sie "(Modalit \ ufffdrovvisoria)" gesehen. Die Option "Ignorieren" hat keinen Platz im Debugging.

In jedem Fall ist die Tatsache, dass einige der Dateinamen einen Fehler hatten, aber mit der Option "ignore" KEINE Zeichen verloren haben (oder NICHT zu verfälschen schienen), verdächtig.

Welcher Teil von "" "Einfügen der Anweisung print repr(folder), repr(f)" "" Hast du nicht verstanden?Alles, was Sie tun müssen, ist so etwas wie dieses:

print "Some meaningful text" # "error reading file" isn't 
print "folder:", repr(folder) 
print "f:", repr(f) 

(13) Es scheint auch, dass Sie UTF-8 an anderer Stelle in Ihrem Code eingeführt haben, durch die Zurückverfolgungs Beurteilung: self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold)

Ich mag würde zu weisen Sie darauf hin, dass Sie immer noch nicht wissen, ob sich Ordner und f auf str-Objekte oder Unicode-Objekte beziehen und zwei Antworten darauf hindeuten, dass sie sehr wahrscheinlich str-Objekte sind. Warum also blahbah.encode() ??

Ein allgemeinerer Punkt: Versuchen Sie zu verstehen, was Ihr Problem ist, bevor Sie Ihr Skript ändern. Es ist nicht der Weg nach vorne, wenn man versucht, jeden Vorschlag zu testen, der mit einer nahezu fehlerfreien Debugging-Technik einhergeht.

(14) Wenn Sie das Skript erneut ausführen, möchten Sie möglicherweise das Volumen der Ausgabe reduzieren, indem Sie es über eine Teilmenge von C: \ ... ausführen, besonders wenn Sie mit meinem ursprünglichen Vorschlag zum Debug-Drucken fortfahren ALLE Dateinamen, nicht nur die fehlerhaften (das Wissen, wie nicht-fehlerhafte aussehen, könnte helfen, das Problem zu verstehen).

Antwort auf Bryan McLemore die "clean up" -Funktion:

(15) Hier ist eine kommentierte interaktive Sitzung, die mit os.walk zeigt, was tatsächlich geschieht() und Nicht-ASCII-Dateinamen:

C:\junk\terabytest>dir 
[snip] 
Directory of C:\junk\terabytest 

20/11/2009 01:28 PM <DIR>   . 
20/11/2009 01:28 PM <DIR>   .. 
20/11/2009 11:48 AM <DIR>   empty 
20/11/2009 01:26 PM    11 Hašek.txt 
20/11/2009 01:31 PM    1,419 tbyte1.py 
29/12/2007 09:33 AM     9 Ð.txt 
       3 File(s)   1,439 bytes 
[snip] 

C:\junk\terabytest>\python26\python 
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] onwin32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from pprint import pprint as pp 
>>> import os 

os.walk (UNICODE_STRING) -> Ergebnisse in Unicode-Objekte

>>> pp(list(os.walk(ur"c:\junk\terabytest"))) 
[(u'c:\\junk\\terabytest', 
    [u'empty'], 
    [u'Ha\u0161ek.txt', u'tbyte1.py', u'\xd0.txt']), 
(u'c:\\junk\\terabytest\\empty', [], [])] 

os.walk (str_string) -> Ergebnisse in s tr Objekte

>>> pp(list(os.walk(r"c:\junk\terabytest"))) 
[('c:\\junk\\terabytest', 
    ['empty'], 
    ['Ha\x9aek.txt', 'tbyte1.py', '\xd0.txt']), 
('c:\\junk\\terabytest\\empty', [], [])] 

cp1252 die Codierung ich erwarten würde auf meinem System verwendet werden ...

>>> u'\u0161'.encode('cp1252') 
'\x9a' 
>>> 'Ha\x9aek'.decode('cp1252') 
u'Ha\u0161ek' 

Decodierung der str mit UTF-8 nicht funktioniert, wie erwartet

>>> 'Ha\x9aek'.decode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\python26\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0x9a in position 2: unexpected code byte 

ANY zufällige Zeichenfolge von Bytes ohne Fehler decodiert werden unter Verwendung von latin1

>>> 'Ha\x9aek'.decode('latin1') 
u'Ha\x9aek' 

ABER U + 009A ist ein Steuerzeichen (SINGLE CHARACTER INTRODUCER), d. H. Bedeutungsloser Kauderwelsch; absolut nichts mit der richtigen Antwort zu tun

>>> unicodedata.name(u'\u0161') 
'LATIN SMALL LETTER S WITH CARON' 
>>> 

(16) Das Beispiel zeigt, was passiert, wenn das Zeichen darstellbarer im Standardzeichensatz ist; Was passiert, wenn es nicht ist? Hier ist ein Beispiel (mit IDLE diese Zeit) eines Dateinamens CJK ideographs enthält, die definitiv nicht darstellbare sind in meinem Standard-Zeichensatz:

IDLE 2.6.4  
>>> import os 
>>> from pprint import pprint as pp 

repr (Unicode Ergebnisse) sieht gut

>>> pp(list(os.walk(ur"c:\junk\terabytest\chinese"))) 
[(u'c:\\junk\\terabytest\\chinese', [], [u'nihao\u4f60\u597d.txt'])] 

und der Unicode wird in IDLE einfach angezeigt:

>>> print list(os.walk(ur"c:\junk\terabytest\chinese"))[0][2][0] 
nihao你好.txt 

Das str Ergebnis wird offenbar durch Verwendung von.kodieren (was auch immer, "ersetzen") - nicht sehr nützlich, z.B. Sie können die Datei nicht öffnen, indem Sie diesen als Dateinamen übergeben.

>>> pp(list(os.walk(r"c:\junk\terabytest\chinese"))) 
[('c:\\junk\\terabytest\\chinese', [], ['nihao??.txt'])] 

So ist die Schlussfolgerung, dass für die besten Ergebnisse, man ein Unicode-String übergeben sollte(), um os.walk und mit allen möglichen Anzeigeproblemen beschäftigen.

+0

getan, wie ist es jetzt? –

+0

das Problem ist, dass die Ausnahme in der Ausnahme passiert, höchstwahrscheinlich, weil die Codierung innerhalb der Probe die gleiche Ausnahme auch auslöst, und ich weiß nicht, wie man weitere Informationen darüber erhält (wie das Zeichen dies verursacht oder wo ist) die erwähnte Datei/Ordner auf meiner Festplatte) –

+0

@terabytest: "weiß nicht, wie man weitere Informationen bekommt" ?? Hast du meine editierte Antwort vor allem in den Teilen (1) und (3) gelesen, wo sie die 'repr()' Funktion erwähnt? –

1

Führen Sie dieses Programm in einem Windows cmd.exe-Feld aus? Wenn ja, versuchen Sie es in IDLE auszuführen und sehen Sie, ob Sie die gleichen Fehler bekommen. Das Cmd.exe-Feld nicht Unicode, nur ascii.

+0

Ich führe dies in IDLE –

2

Sie versuchen, eine Aktion (z. B. Drucken) für eine Unicode-Zeichenfolge auszuführen, die Nicht-ASCII-Zeichen enthält, und die Zeichenfolge wird standardmäßig in ASCII konvertiert. Sie müssen die Codierung angeben, um die Zeichenfolge korrekt darzustellen.
Es würde erheblich helfen, wenn Sie einige Beispielcode von dem, was Sie versuchen, zu veröffentlichen.

Der einfachste Weg, dies zu tun wäre:
s = u'ma\xf1ana';
print s.encode('latin-1');

Herausgegeben nach Details zur Frage hinzugefügt:

In Ihrem Fall, dass Sie die Zeichenfolge, die Sie zuerst lesen entschlüsseln müssen:
f.decode();,
so versuchen,
u"%s/%s" % (folder, f)zu ändern 10 zu
os.path.join(folder, f.decode())

Hinweis, dass ‚Latin-1‘ Codierung geändert erforderlich sein könnte, was Ihre Datei mit

PS benannt: John Machin sehr hilfreichen Möglichkeiten zur Verbesserung und aufzuräumen erwähnt hat die Code.

+1
+0

Ja, ich versuche, die Zeichenfolge zu drucken. Wie sage ich es nicht Ascii zu verwenden? –

+0

Das einfachste Beispiel wäre wie folgt: s = u'ma \ xf1ana ';
drucken s.encode ('latin-1') – artdanil

+0

kann keinen Kommentar erhalten, um Code-Beispiel richtig anzuzeigen, also lege ich es in die Antwort. – artdanil

1
u"%s" % f 

An verschiedenen Stellen machen Sie etwas Ähnliches wie oben beschrieben. Dies ist genau der falsche Weg, um ein Str-Objekt in ein Unicode-Objekt zu konvertieren, da die Konvertierung mit sys.getdefaultencoding() (ascii) durchgeführt wird, was fast garantiert falsch ist.

Sie sollten die encode/decode-Methoden verwenden, um zu/von einem Unicode-Objekt zu konvertieren. Dies erfordert, dass Sie wissen, was Ihre Eingabe codiert (die von os.walk zurückgegebenen Zeichenfolgen). Z. B. wenn die Dateinamen in codierten werden UTF-8

uf = f.decode('utf-8') 

wird f als UTF-8-codierte Folge von Bytes interpretieren und die richtige Unicode-Objekt zurückzugeben. Wenn Sie das Unicode-Objekt ausgeben möchten, würden Sie es in ähnlicher Weise zurück in eine Str konvertieren und die gültige Codierung angeben, unter der Sie es ausgeben möchten.

print uf.encode('utf-8') 
+0

Ich bekomme immer noch die gleiche UnicodeDecodeError: 'Ascii' Codec kann Byte 0x99 in Position 125 nicht dekodieren: Ordnungszahl nicht im Bereich (128), obwohl ich geschrieben schrieb "Fehler beim Lesen der Datei% s"% ("% s /% s" % (Ordner, f)) .decodieren ("utf-8") ... Wth –

+0

Das Thema dreht sich um Windows-Dateipfade, also ist utf8 ungefähr so ​​relevant wie latin1. –

+0

Mein Beitrag war, bevor er diese Information hinzufügte, und sollte allgemeine Information sein, die Probleme mit dem verwendeten Ansatz erklärt. Das Verständnis dieser Probleme hilft, unabhängig davon, was die eigentliche Kodierung ist. Leider wurde mein Beitrag zum Nennwert genommen und nicht als allgemeine Beschreibung. – jamessan

-1

anstatt das zu tun:

print "Error reading file %s"%u"%s/%s"%(folder, f) 

Try this:

print "Error reading file %s"%u"%s/%s"%(folder.encode('ascii','ignore'), f.encode('ascii','ignore')) 

Da die Konsole nicht Unicode-Zeichen drucken können, können Sie die den richtigen Namen sehen. 'Ignorieren' weist den Codec an, diese Zeichen zu überspringen. Sie können auch 'replace' (druckt ein '?'), 'xmlcharrefreplace' (ersetzt durch & x #### des Codepunkts), 'backslashreplace' (ersetzt durch \ x ###### des Codes)

Sie müssen jeden Unicode-String wie diesen, den Sie drucken, codieren.

+0

Ich bekomme immer noch diese UnicodeDecodeError: 'Ascii' Codec kann Byte 0x99 in Position 25 nicht dekodieren: ordinal nicht im Bereich (128) ist es ein Geheimnis –

+0

hast du 'du' auch codieren? Ich habe das nicht bemerkt – Knio

+0

Und mit "ignorieren" wird ihn den "richtigen Namen" sehen lassen ??? –

0

Ich hatte das Pech, in einigen Codebasen zu arbeiten, die nicht mit ihrer Codierung übereinstimmten.

Dies ist eine Funktion, die wir ihm helfen, bis zur Reinigung:

def to_unicode(value): 
    if isinstance(value, unicode): 
     return value 
    elif isinstance(value, str): 
     try: 
      if value.startswith('\xff\xfe'): 
       return value.decode('utf-16-le') 
      elif value.startswith('\xfe\xff'): 
       return value.decode('utf-16-be') 
      else: 
       return value.decode('utf-8') 
     except UnicodeDecodeError: 
      return value.decode('latin-1') 
    else: 
     try: 
      return unicode(value) 
     except UnicodeError: 
      return to_unicode(str(value)) 
     except TypeError: 
      if hasattr(value, '__unicode__'): 
       return value.__unicode__() 

Also diese Funktion verwenden Sie verwenden können:

print u"Error reading file %s/%s" % (to_unicode(folder), to_unicode(f)) 
+0

Wie können Sie sich vorstellen, dass Namen von Verzeichnissen und Dateien, die von os.walk() unter Windows zurückgegeben werden, nicht konsistent codiert werden? Diese Namen haben keine UTF-16-Stücklisten, daher wird Ihr Code UTF8 versuchen, was bei einem Nicht-ASCII-Byte fehlschlagen wird. In diesem Fall geben Sie die mit latin1 dekodierte Zeichenkette zurück, IOW-Unsinn ohne Anzeichen dafür, dass ein Problem vorliegt! Sehen Sie meine aktualisierte Antwort für ein Beispiel. –

+1

Wenn Sie mehr als den Codeblock lesen, sehen Sie, dass dies keine maßgeschneiderte Funktion ist, um diese Frage zu bearbeiten. Es ist eine allgemeine to_unicode-Funktion, von der ich gehofft hatte, dass sie ihm helfen würde. Ihr Kommentar ist weit davon entfernt, konstruktiv und stattdessen sehr aufrührerisch und höchst unangemessen zu sein. –

+0

Ich sah es war eine allgemeine to_unicode Funktion.Wenn das str-Objekt nicht in latin1 oder UTF-8 codiert ist und nicht mit einer UTF-16-BOM beginnt, entschlüsselt es Ihre Routine mit latin1, was NICHT hilfreich ist - weil LATIN1 BYTESEQUENZEN DECODIERT OHNE FEHLER verdeckt Ihre Routine das Problem. Sehen Sie sich mein Beispiel an, in dem Ihre Prozedur ein in cp1252 codiertes str annimmt und Unicode mit einem Steuerzeichen zurückgibt. Solche Ergebnisse sind bedeutungsloser Müll und es muss gesagt werden, dass sie bedeutungsloser Müll sind - sowohl für das OP als auch für Ihre eigenen Anwendungen. –

6

Python verwendet ASCII-Kodierung standardmäßig was ärgerlich ist. Wenn Sie es dauerhaft ändern möchten, suchen und bearbeiten Sie site.py Datei, suchen Sie nach def setencoding() und einige Zeilen unter Änderung encoding = "ascii" zu encoding = "utf-8". Tschüss, tschüss Standard-ASCII-Codierung.

Verwandte Themen