Sie sind über das allgemeine Problem mit Codierungen gestolpert: Wie kann ich feststellen, in welcher Codierung eine Datei enthalten ist?
Antwort: Dies ist nur möglich, wenn das Dateiformat dies vorsieht. XML beginnt beispielsweise mit:
<?xml encoding="utf-8"?>
Dieser Header wurde sorgfältig ausgewählt, damit er unabhängig von der Codierung gelesen werden kann. In Ihrem Fall gibt es keinen solchen Hinweis, daher haben weder Ihr Editor noch Python eine Ahnung, was los ist. Daher müssen Sie das codecs
Modul verwenden und verwendencodecs.open(path,mode,encoding)
, das das fehlende Bit in Python bereitstellt.
Bei Ihrem Editor müssen Sie prüfen, ob er eine Möglichkeit zum Festlegen der Codierung einer Datei bietet.
Der Zweck von UTF-8 besteht darin, 21-Bit-Zeichen (Unicode) als 8-Bit-Datenstrom codieren zu können (da dies das einzige ist, was alle Computer auf der Welt verarbeiten können). Da die meisten Betriebssysteme jedoch älter sind als die Unicode-Ära, verfügen sie nicht über geeignete Tools, um die Codierungsinformationen an Dateien auf der Festplatte anzuhängen.
Das nächste Problem ist die Darstellung in Python. Dies wird im Kommentar von heikogerlach perfekt erklärt . Sie müssen verstehen, dass Ihre Konsole nur ASCII anzeigen kann. Um Unicode oder irgendetwas> = Zeichencode 128 anzuzeigen, muss ein Escape-Mittel verwendet werden. In Ihrem Editor dürfen Sie nicht die maskierte Anzeigezeichenfolge eingeben, sondern die Bedeutung der Zeichenfolge (in diesem Fall müssen Sie den Umlaut eingeben und die Datei speichern).
Sie können jedoch die Python-Funktion eval () verwenden, um eine maskierte Zeichenfolge in eine Zeichenfolge umzuwandeln:
>>> x = eval("'Capit\\xc3\\xa1n\\n'")
>>> x
'Capit\xc3\xa1n\n'
>>> x[5]
'\xc3'
>>> len(x[5])
1
Wie Sie sehen können, wurde die Zeichenfolge "\ xc3" in ein einzelnes Zeichen umgewandelt. Dies ist jetzt eine 8-Bit-Zeichenfolge, UTF-8-codiert. So erhalten Sie Unicode:
>>> x.decode('utf-8')
u'Capit\xe1n\n'
Gregg Lind fragte: Ich denke, hier fehlen einige Teile: Die Datei f2 enthält: hex:
0000000: 4361 7069 745c 7863 335c 7861 316e Capit\xc3\xa1n
codecs.open('f2','rb', 'utf-8')
Liest sie beispielsweise alle in separaten Zeichen (erwartet). Gibt es eine Möglichkeit, in eine Datei in ASCII zu schreiben, die funktionieren würde?
Antwort: Das hängt davon ab, was Sie meinen. ASCII kann keine Zeichen> 127 darstellen. Sie müssen also sagen, dass die nächsten Zeichen etwas Besonderes bedeuten, wie es die Sequenz "\ x" tut. Es heißt: Die nächsten beiden Zeichen sind der Code eines einzelnen Zeichens. "\ u" macht dasselbe mit vier Zeichen, um Unicode bis zu 0xFFFF (65535) zu codieren.
Sie können Unicode also nicht direkt in ASCII schreiben (da ASCII einfach nicht dieselben Zeichen enthält). Sie können es als Escapezeichenfolge schreiben (wie in f2). In diesem Fall kann die Datei als ASCII dargestellt werden. Oder Sie können es als UTF-8 schreiben. In diesem Fall benötigen Sie einen sicheren 8-Bit-Stream.
Ihre Lösung decode('string-escape')
funktioniert, aber Sie müssen wissen, wie viel Speicher Sie verwenden: Dreifache Menge an Speicher codecs.open()
.
Denken Sie daran, dass eine Datei nur eine Folge von Bytes mit 8 Bits ist. Weder die Bits noch die Bytes haben eine Bedeutung. Sie sagen "65 bedeutet 'A'". Da \xc3\xa1
"à" werden sollte, der Computer jedoch keine Mittel zum Wissen hat, müssen Sie dies durch Angabe der Codierung angeben, die beim Schreiben der Datei verwendet wurde.