Seite 1 von 1
Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 20:37
von Mareike
Hallo,
Ich parse mit python 3.3 Textdateien, die im (oktal) isolatin1-Format vorliegen.
Dabei erhalte ich Strings, wobei die Sonderzeichen als ASCII-Codierungen enthalten sind.
so zB "\133Unit\135" anstatt "[Unit]".
Jetzt ist meine Frage wie ich den String kovertieren muss, damit die ASCII Codierung in das entsprechende Charakter umgewandelt wird.
Die Konsole wandelt richtig um:
In meinem Programm wird weiterhin die ASCII-Codierung ausgegeben.
Code: Alles auswählen
self.fobj = codecs.open(filename, 'r','latin_1');
self.fobj_out = codecs.open(savefile,"w","UTF-8")
text = self.fobj.read()
result = re.finditer(r,text,re.I)
for line in result:
self.fobj_out.write(str(i)+ str(line.group(1)) +"\n")
i=i+1
self.fobj.close()
self.fobj_out.close()
Kann mir jemand helfen wie ich das umwandeln kann?
Grüße,
Mareike
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 20:49
von BlackJack
@Mareike: Die Einrückung bei Deinem Quelltext stimmt nicht.
Dateien sollte man mit der ``with``-Anweisung verwenden. Ich vermute mal ganz stark es macht keinen Sinn die beiden Dateien an das Objekt zu binden. Also weg mit dem `self`.
Die literale Zeichenkette in der Python-Shell wird vom Python-Compiler interpretiert, die Daten die durch Dein Programm verarbeitet werden nicht. Eine Zeichenkette die Ziffern in einem Zahlensystem wie zum Beispiel Oktal enthalten kann man mit der `int()`-Funktion in eine Zahl umwandeln. Und eine Zahl, die einen Unicode-Codepoint enthält kann man mit der `chr()`-Funktion in eine Zeichenkette umwandeln, die das dazugehörige Zeichen enthält. Mit dem `re`-Modul kann man einen regulären Ausdruck formulieren der die Escapesequenzen mit den Oktalzahlen findet, und mit der `sub()`-Funktion/-Methode kann man in Zeichenketten mit regulären Ausdrücken suchen und ersetzen. Für die Ersetzung kann man auch eine Funktion angeben, die für jeden Treffer mit einem `Match`-Objekt aufgerufen wird, und eine Zeichenkette zurück gibt, durch die der Treffer ersetzt werden soll. Diese Puzzleteile muss man jetzt nur noch zu einem Programm zusammensetzen.

Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 21:23
von cmax
f = open(filename, 'rb')
bs = f.read()
f.close()
s = bs.decode('ISO-8859-1').encode('utf8').decode('unicode_escape')
print(s)
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 21:28
von BlackJack
@cmax: Wobei das mehr umwandelt als nur oktale Escapes.
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 21:33
von Mareike
@Blackjack: Danke für die schnelle Antwort. Der Codeausschnitt ist Teil einer etwas umfangreicheren tkinter-GUI, daher das "self" und die fehlerhafte Einrückung. int() und chr() Funktionen hab ich schon getestet, würde die Lösung allerdings gerne hinten anstellen, da die Textdateien sehr viele Kontrollsequenzen enthalten...
@cmax: hab ich auch schon versucht:
string.encode('utf-8').decode('latin_1')
Allerdings bekomm ich hierbei für Python 3.X die Fehlermeldung:
"AttributeError: 'str' object has no attribute 'decode'".
Gehts nicht was ähnliches in python 3?
Grüße,
Mareike
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 21:57
von cmax
BlackJack hat geschrieben:@cmax: Wobei das mehr umwandelt als nur oktale Escapes.
Stimmt. Das könnte je nach Text zu Problemen führen.
@Mareike:
Mein Code ist für Python3.
Deine Fehlermeldung ist insofern verständlich, dass str (in Python3) nicht decodiert werden kann - ist er ja schon.
Aber eigentlich sollte
string.encode('utf-8') doch eine Instanz von
bytes zurückliefern.

Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 22:08
von Mareike
cmax hat geschrieben:
@Mareike:
Mein Code ist für Python3.
Deine Fehlermeldung ist insofern verständlich, dass str (in Python3) nicht decodiert werden kann - ist er ja schon.
Aber eigentlich sollte
string.encode('utf-8') doch eine Instanz von
bytes zurückliefern.

Ja, stimmt, wenn es alleine steht:
<class 'bytes'>
Ich dachte bisher wenn ich
ausführe, interpretiert Python den latin-string automatisch nach Unicode.
Grüße,
Mareike
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 22:18
von BlackJack
@Mareike: cmax hat die Daten als Bytes eingelesen und Du lässt sie beim Einlesen schon dekodieren. Bei ``string.encode('utf-8').decode('latin_1')`` kann die von Dir behauptete Fehlermeldung unter Python 3.x nicht kommen. `string` muss vom Typ `str` sein und nach dem `encode()` hast Du ein Objekt vom Typ `bytes`, und *das* hat ganz sicher eine `decode()`-Methode. Der Ausdruck macht in Deinem Kontext aber auch gar keinen Sinn, denn wenn `string` eine korrekte Unicode-Zeichenkette ist, dann kommt da „Müll” bei heraus. Zumindest wenn etwas ausserhalb von ASCII enthalten ist.
Edit: Das `self` bei den Dateiobjekten macht keinen Sinn. Falls Du das anders siehst, könntest Du mal erklären warum man geschlossene Dateiobjekte auf dem Objekt haben möchte auf dem die Methode existiert.
Und falls Du die `re.sub()`-Lösung mit `int()` und `chr()` nicht nimmst, weil Du denkst das könnte zu langsam sein: Das wage ich zu bezweifeln. Wenn Du damit leben kannst, das 'unicode-escape' mehr als nur Oktalzahlen-Escapesequenzen ersetzt, dann ist das natürlich trotzdem die einfachere Lösung.
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Montag 4. Februar 2013, 23:49
von Mareike
@Blackjack:
Habs jetzt so gemacht, wie von dir empfohlen. Klappt wirklich gut

Vielen Dank! Muss ich jetzt mal für verschiedene Dateien testen. Wobei ich immer noch nicht versteh, warum das mit der Codierung nicht funktioniert... naja, mal wieder kostenlose Lebenszeit verschwendet
Wegen dem self-Objekt:
Code: Alles auswählen
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
def createWidgets(self)
...
def konvert (self):
...
root = tk.Tk()
app = Application(master=root)
app.mainloop()
Das ist das Grundgerüst meiner GUI, und ich speicher alle Variablen in dem self-objekt. Warum ich das mache, keine Ahnung, war in irgendeinem Programmbeispiel aus der Python-Doc...

Lasse mich aber gerne belehren
Grüße,
Mareike
Re: Konvertierung iso latin 1 --> utf8
Verfasst: Dienstag 5. Februar 2013, 00:36
von BlackJack
@Mareike: Du speicherst nicht alle Objekte als Attribute. `text`, `result`, `line`, und `i` zum Beispiel nicht. Warum also die Dateiobjekte? Auf ein Objekt gehört alles was den Zustand des Objektes ausmacht als Attribut. Und zwar sollten alle Attribute nach Abarbeitung der `__init__()`-Methode existieren, denn diese Methode initialisiert den Zustand eines Objektes und das sollte danach vollständig initialisiert sein. Wenn in anderen Methoden neue Attribute hinzugefügt werden, dann gehören die da in aller Regel nicht hin und irgend etwas am Entwurf ist falsch oder zumindest fragwürdig.
Und wenn innerhalb einer Methode das `self`-Argument überhaupt nicht verwendet wird, dann ist auch etwas komisch. Denn dann ist die Methode eigentlich gar keine Methode und man sollte sich Fragen warum eine normale Funktion in eine Klasse gesteckt wurde. Falls es dafür einen Grund gibt, sollte man den dokumentieren. Im DocString, aber mindestens dadurch, dass man `staticmethod()` als „decorator” verwendet.