Sie sind über das allgemeine Problem mit Kodierungen gestolpert: Wie kann ich feststellen, in welcher Kodierung eine Datei vorliegt?
Antwort: Sie können nicht es sei denn, das Dateiformat sieht dies vor. XML zum Beispiel beginnt mit:
<?xml encoding="utf-8"?>
Diese Kopfzeile wurde sorgfältig ausgewählt, damit sie unabhängig von der Kodierung gelesen werden kann. In Ihrem Fall gibt es keinen solchen Hinweis, so dass weder Ihr Editor noch Python eine Ahnung davon haben, was vor sich geht. Daher müssen Sie die codecs
Modul und verwenden codecs.open(path,mode,encoding)
die das fehlende Bit in Python liefert.
Was Ihren Editor betrifft, müssen Sie prüfen, ob er eine Möglichkeit bietet, die Kodierung einer Datei einzustellen.
Der Sinn von UTF-8 besteht darin, 21-Bit-Zeichen (Unicode) als 8-Bit-Datenstrom zu kodieren (denn das ist das Einzige, was alle Computer der Welt verarbeiten können). Da aber die meisten Betriebssysteme aus der Zeit vor der Unicode-Ära stammen, verfügen sie nicht über geeignete Werkzeuge, um die Kodierungsinformationen an Dateien auf der Festplatte anzuhängen.
Das nächste Problem ist die Darstellung in Python. Dies wird perfekt erklärt in der Kommentar von heikogerlach . Sie müssen wissen, dass Ihre Konsole nur ASCII anzeigen kann. Um Unicode oder irgendetwas >= Zeichencode 128 anzeigen zu können, muss sie irgendeine Art von Escaping verwenden. In Ihrem Editor müssen Sie nicht die maskierte Zeichenfolge eingeben, sondern die Bedeutung der Zeichenfolge (in diesem Fall müssen Sie die Umlaute eingeben und die Datei speichern).
Sie können jedoch die Python-Funktion eval() verwenden, um eine maskierte Zeichenkette in eine Zeichenkette zu verwandeln:
>>> x = eval("'Capit\\xc3\\xa1n\\n'")
>>> x
'Capit\xc3\xa1n\n'
>>> x[5]
'\xc3'
>>> len(x[5])
1
Wie Sie sehen können, ist die Zeichenfolge " \xc3 " wurde in ein einzelnes Zeichen umgewandelt. Dies ist nun eine 8-Bit-Zeichenkette, UTF-8 kodiert. Um Unicode zu erhalten:
>>> x.decode('utf-8')
u'Capit\xe1n\n'
Gregg Lind gefragt: Ich glaube, 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')
Gibt es irgendeine 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 brauchen also eine Möglichkeit zu sagen: "Die nächsten Zeichen bedeuten etwas Besonderes", was die Sequenz " \x " tut. Sie sagt: Die nächsten zwei Zeichen sind der Code eines einzelnen Zeichens. " \u " macht das Gleiche mit vier Zeichen, um Unicode bis 0xFFFF (65535) zu kodieren.
Man kann also nicht direkt Unicode in ASCII schreiben (weil ASCII einfach nicht die gleichen Zeichen enthält). Sie können sie als String-Escapes schreiben (wie in f2); in diesem Fall kann die Datei als ASCII dargestellt werden. Oder Sie können sie als UTF-8 schreiben; in diesem Fall benötigen Sie einen sicheren 8-Bit-Stream.
Ihre Lösung mit decode('string-escape')
funktioniert, aber Sie müssen sich darüber im Klaren sein, wie viel Speicherplatz Sie verwenden: Dreimal so viel wie bei der Verwendung von 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 sind es, der sagt: "65 bedeutet 'A'". Seit \xc3\xa1
zu "à" werden soll, aber der Computer keine Möglichkeit hat, dies zu erkennen, müssen Sie ihm die Kodierung mitteilen, die beim Schreiben der Datei verwendet wurde.