2010-02-03 3 views
6

Wie erzwinge ich Latin-1 (was ich glaube, iso-8859-1?) Dateiausgabe in Python?Python: Wie erzwinge ich ISO-8859-1 Dateiausgabe?

Hier ist mein Code im Moment. Es funktioniert, aber der Versuch, die resultierende Ausgabedatei in eine Latin-1-MySQL-Tabelle zu importieren, ergibt weird encoding errors.

outputFile = file("textbase.tab", "w") 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write(complete_line) 
    outputFile.write("\n") 
outputFile.close() 

Die resultierende Ausgabedatei scheint bekomme ich immer noch seltsame Codierung Probleme in "Western (Mac OS Roman)", aber wenn ich dann speichern Sie es in Latin-1, um gerettet zu werden. Wie kann ich sicherstellen, dass die verwendeten Zeichenfolgen und die Datei selbst alle in Latin-1 codiert sind, sobald sie generiert werden?

Die ursprünglichen Zeichenfolgen (im textData Wörterbuch) wurden aus einer RTF-Datei analysiert - ich weiß nicht, ob das einen Unterschied macht.

Ich bin ein wenig neu zu Python und Codierung im Allgemeinen, so entschuldigt, wenn dies eine dumme Frage ist. Ich habe versucht, mir die Dokumente anzusehen, bin aber nicht sehr weit gekommen.

Ich benutze Python 2.6.1.

Antwort

10

Verwenden Sie einfach den codecs Modul für die Datei zu schreiben:

import codecs 
outputFile = codecs.open("textbase.tab", "w", "ISO-8859-1") 

Natürlich können die Strings Sie Unicode-Strings schreiben werden müssen (Typ unicode), werden sie nicht umgesetzt werden, wenn sie schlicht str Objekte (das sind im Grunde nur Arrays von Bytes). Ich nehme an, dass Sie die RTF-Datei mit dem normalen Python-Dateiobjekt auch lesen, also müssen Sie möglicherweise das zu codecs.open auch umwandeln.

0

Ich denke, es ist nur:

outputFile = file("textbase.tab", "wb") 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write((complete_line + "\n").encode("iso-8859-1")) 
    outputFile.close() 

Wie Sie erwähnt, müssen Sie sicherstellen, dass Sie die RTF-Datei zu korrekt entschlüsseln. Damit dies funktioniert, sollten k und v Unicode-Objekte sein.

+0

Vielen Dank. Ich habe gerade diesen Code versucht, aber bekomme: "UnicodeDecodeError: 'ascii' Codec kann Byte 0xa3 in Position 753 nicht dekodieren: Ordnungszahl nicht im Bereich (128)". Ich werde jetzt versuchen, sicherzustellen, dass k und v Unicode-Objekte sind, wie oben vorgeschlagen. – AP257

0

Das Hauptproblem hier ist, dass Sie nicht wissen, in welcher Kodierung Ihre Daten sind. Wenn wir annehmen, dass Sie korrekt sind, dass Ihre Datei in Mac OS Roman ist, müssen Sie zuerst die Daten als Unicode dekodieren und codiere es dann als iso-8859-1.

inputFile = open("input.rtf", "rb") # The b flag is just a marker in Python 2. 
data = inputFile.read().decode('mac_roman') 
textData = yourparsefunctionhere(data) 

outputFile = open("textbase.tab", "wb") # don't use file() 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write((complete_line + "\n").encode("iso-8859-1")) 
    outputFile.close() 

Aber ich würde nicht überrascht sein, da es RTF ist, wenn es von Windows ist verschlüsselt, so dass Sie auch versuchen, vielleicht wollen. Ich weiß nicht, wie RTF die Kodierung angibt.

+0

Wenn Sie r anstelle von rb verwenden, wird Windows \ r \ n in \ r (einschließlich auf Python 2.6). –

+0

Aus der Dokumentation: "Hängen Sie 'b' an den Modus an, um die Datei im Binärmodus zu öffnen, auf Systemen, die zwischen Binär- und Textdateien unterscheiden. Auf Systemen, die diese Unterscheidung nicht haben, hat das Hinzufügen von 'b' keine Auswirkung. " Das Vorhandensein von b oder t (oder keiner von ihnen) macht überhaupt keinen Unterschied auf Unix. Du denkst vielleicht an "U", was universelle Zeilenumbrüche sind.* Es * machts Zeilenenden (habe niemals U beim Schreiben!) Welche Systeme, die zwischen Text- und Binärdateien unterscheiden, weiß ich nicht. Unix sicher nicht. –

0

Für mich io.open arbeitet etwas schneller auf Python 2.7 für schreibt, und eine Größenordnung schneller für lautet:

import io 
with io.open("textbase.tab", "w", encoding="ISO-8859-1") as outputFile: 
    ... 

In Python 3, können Sie einfach pass the encoding keyword arg to open.

Verwandte Themen