Encoding von Skripten konvertieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hallo,

Ich habe eventuell vor meine Python-Skripte auf UTF-8 oder sogar Unicode umzuändern.
Momentan liegen meine Skripte alle im Encoding iso-8859-1 vor.

Gibt es eine schnelle Möglichkeit ganze Dateien (*.py) von einem Encoding in ein anderes Encoding zu übertragen?
Habt ihr dazu eine Idee?
Gruß, Harry
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

HarryH hat geschrieben:Ich habe eventuell vor meine Python-Skripte auf UTF-8 oder sogar Unicode umzuändern. Momentan liegen meine Skripte alle im Encoding iso-8859-1 vor.
Ich verwende WingIDE dafür. Schreibst du nach dem Öffnen des Python-Moduls in den Kopf ``# -*- coding: utf-8 -*-``, dann wird das Modul beim Speichern automatisch nach UTF-8 umgewandelt.
Das funktioniert auch mit der WingIDE-Testversion.

mfg
Gerold
:-)

PS: Es gibt kein "oder sogar Unicode"... ;-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hi Gerold,

Danke für die schnelle Antwort!

Leider ist mir auch das zu umständlich. Ich ca. 130 Skripte.
Gibt es keine schneller Möglichkeit?

Noch eine andere Frage:
Ist es überhaupt zu empfehlen, auf UTF-8 umzusteigen? Ich hatte gelesen das dies in Zukunft Standard werden soll. Deswegen dachte ich mir lieber früher als später umsteigen.
Gruß, Harry
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

HarryH hat geschrieben:Leider ist mir auch das zu umständlich. Ich ca. 130 Skripte.

Ist es überhaupt zu empfehlen, auf UTF-8 umzusteigen?
Hallo HarryH!

Du wärst in 21 min. fertig, wenn du für jedes Skript zehn Sekunden brauchen würdest.

Wenn du unter Windows arbeitest, dann entgehst du Problemen (auch mit MS-Datenbanken), wenn du bei "iso-8859-1" oder "iso-8859-15" bleibst. Dann kommt jeder Editor damit klar und wenn du Daten aus MsSQL-Datenbanken holst, sind die im gleichen Encoding.

Wenn du unter Linux arbeitest, dann solltest du sowiso mal auf UTF-8 umsteigen. Das ist die Zukunft. Das heißt aber, auch unter Linux gilt: Verwende das Encoding für die Python-Module, das bei dir eingestellt ist. Der Kommandozeilenbefehl "locale" gibt Auskunft darüber, was bei dir eingestellt ist.

Du kannst natürlich alles auch in UTF-8 schreiben. Auch dann, wenn dein Betriebssystem das nicht unterstützt. Es kommt auf den Editor an, den du benutzt. Wenn du diesen so einstellen kannst, dass alles in UTF-8 gespeichert wird, dann ist das keine schlechte Wahl. Es besteht aber keine Notwendigkeit, alles nach UTF-8 umzuwandeln.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Unterscheiden sich denn überhaupt bspw. in ISO-8859-1 und (ohne BOM) UTF-8 kodierte Dateien von einander, wenn sie nur ASCII-Zeichen enthalten? Dann würde es ja reichen, die coding-Zeile für UTF-8 automatisiert einfügen zu lassen, wenn man PEP 8-konform sowieso nur englische Docstrings und Kommentare sowie keine nicht-ASCII-Zeichen verwendet hat.
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hallo Gerold,

Danke für deine Hinweise, besonders den ersten :D
Jetzt habe ich gleich noch ein paar Fragen :lol:

Was passiert eigentlich wenn ich in einem Programm, Module mit unterschiedlichen Encodings lade, z.B. UFT-8 und iso-8859-15?

Welches wird verwendet? Oder funktioniert es einfach so lange bis Fehler auftreten (das ist natürlich mit allem so)?

Außerdem hatte ich letztens Probleme, mit in der registry (ich arbeite mit Windows) abgespeicherten Pfaden. Diese wurden mir über die Funktion "_winreg.EnumValue()" nämlich nur als Unicode-Strings zurückgegeben.
Ich habe sie dann mit obj.encode("iso-8859-1") in mein internes Encoding umgewandelt. Danach tauchten Fehler innerhalb meines Programms auf.

Mit obj.encode(sys.getfilesystemencoding()) konnte ich diese Fehler dann ausschließen. Aber ob das der richtige Weg ist, weiß ich nun auch nicht?

Auch mit in zipfiles enthaltenen Namen hatte ich schon des öfteren Probleme bei der korrekten Anzeige dieser Namen. Dabei decodiere ich sie mit obj.decode("cp437") nach unicode und danach mit obj.encode("iso-8859-1") in mein internes Enoding. Trotzdem, einige Zeichen werden falsch dargestellt.

Aus diesen und anderen Gründen, frage ich mich ob die Probleme mit UTF-8 verringert werden könnten, da ich damit doch alle (Unicode-)Zeichen korrekt darstellen kann (geeigneten Editor vorausgesetzt)?
Gruß, Harry
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Y0Gi hat geschrieben:Unterscheiden sich denn überhaupt bspw. in ISO-8859-1 und (ohne BOM) UTF-8 kodierte Dateien von einander, wenn sie nur ASCII-Zeichen enthalten?
Hallo Y0Gi!

Die ersten 128 Zeichen der "UTF-8"-Kodierung unterscheiden sich nicht von den 128 Zeichen der "ASCII"-Kodierung. Das ist ja der große Vorteil von UTF-8.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo HarryH!
HarryH hat geschrieben:Danke für deine Hinweise, besonders den ersten :D
Gerne geschehen. ;-)
HarryH hat geschrieben:Was passiert eigentlich wenn ich in einem Programm, Module mit unterschiedlichen Encodings lade, z.B. UFT-8 und iso-8859-15? Welches wird verwendet?
Gar nichts, wenn diese ein Encoding-Cookie (z.B. ``# -*- coding: utf-8 -*-``) enthalten, damit der Pyhton-Interpreter weiß, in welchem Encoding diese Module gespeichert wurden.
Diese Encoding-Cookies gelten für die einzelnen Dateien nicht für das gesamte Programm.
HarryH hat geschrieben:Aus diesen und anderen Gründen, frage ich mich ob die Probleme mit UTF-8 verringert werden könnten
Die Umwandlung nach UTF-8 verringert deine geschilderten Problem nicht. Das einzige was sich ändert ist, dass du in deinen Programmen die Strings dann statt nach "iso-8859-1" nach "utf-8" umwandeln müsstest.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Dienstag 19. Juni 2007, 12:35, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

@HarryH: Du solltest Dich mal umfassend über Kodierungen informieren. Das was Du vorhast, alle Quelltexte nach UTF-8 kodieren, um vielleicht Probleme zu beheben die Du nicht nachvollziehen kannst, ist keine Lösung sondern Voodoo. ;-)

Wenn Du Dich schon mit Unicode auseinandersetzt, dann sollte die "interne" Kodierung gar keine sein, sondern es sollten soweit es möglich ist Unicode-Zeichenketten verwendet werden und nur an den "Ein-" und "Ausgängen" entsprechende Kodierungen vorgenommen werden.

Man kann auch nicht viel sagen, wenn Du einfach nur sagst, "dann tauchten Probleme auf". Wenn die durch eine andere Kodierung gelöst werden konnten, bedeutet das wohl, dass die Unicode-Zeichenkette aus der Registry, Zeichen enthielt, die in "iso-8859-1" nicht enthalten sind. Das ist einer Gründe warum man innerhalb eines Programms bei Unicode bleiben und ausserhalb versuchen sollte eine Kodierung wie UTF-8 oder UTF-16 zu verwenden. Dann können nämlich alle Zeichen verarbeitet und gespeichert werden.

Welche Kodierung der Quelltext hat ist egal solange: a) der coding-Kommentar mit der tatsächlichen Kodierung übereinstimmt und man b) keine Zeichen ausserhalb von ASCII in normalen Zeichenketten verwendet. Der coding-Kommentar sagt Python "nur" welche Kodierung zum dekodieren von literalen Unicode-Zeichenketten im Quelltext verwendet werden soll.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Allgemeine Info's zum Thema Unicode: [wiki]Unicode[/wiki]
:lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hallo BlackJack,
BlackJack hat geschrieben:@HarryH: Du solltest Dich mal umfassend über Kodierungen informieren. Das was Du vorhast, alle Quelltexte nach UTF-8 kodieren, um vielleicht Probleme zu beheben die Du nicht nachvollziehen kannst, ist keine Lösung sondern Voodoo. ;-)
Das sollte ich wirklich (mich informieren) und ich bin gerade dabei. :lol:
BlackJack hat geschrieben:Wenn Du Dich schon mit Unicode auseinandersetzt, dann sollte die "interne" Kodierung gar keine sein, sondern es sollten soweit es möglich ist Unicode-Zeichenketten verwendet werden und nur an den "Ein-" und "Ausgängen" entsprechende Kodierungen vorgenommen werden.
Was meinst du hier mit 'interne' Codierung? Ich meinte damit den speziellen Kommentar in der ersten Zeile der Datei.
Unicode-Zeichenketten werden mit 'u' vor dem String bezeichnet, oder?
Habe ich das richtig verstanden, der spezielle Kommentar gilt nur für die Zeichen die ich in meinen Quelltext schreibe?
Woher weiß ich eigentlich in welcher Codierung mein Editor speichert?
BlackJack hat geschrieben:Man kann auch nicht viel sagen, wenn Du einfach nur sagst, "dann tauchten Probleme auf". Wenn die durch eine andere Kodierung gelöst werden konnten, bedeutet das wohl, dass die Unicode-Zeichenkette aus der Registry, Zeichen enthielt, die in "iso-8859-1" nicht enthalten sind. Das ist einer Gründe warum man innerhalb eines Programms bei Unicode bleiben und ausserhalb versuchen sollte eine Kodierung wie UTF-8 oder UTF-16 zu verwenden. Dann können nämlich alle Zeichen verarbeitet und gespeichert werden.
Du hast recht. Hier sind meine zwei Funktionen zum Lesen, bzw. Schreiben in die registry.

Code: Alles auswählen

def SetRegistryEntrys(self, folder, entrys):
        path = "%s\%s" % (self.winregPath, folder)
        key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, path)
        i = -1
        for i, entry in enumerate(entrys):
            name = "%02i" % i
            _winreg.SetValueEx(key, name, 0, _winreg.REG_SZ, entry)
        #Lösche überflüssige entrys
        while 1:
            i += 1
            try:
                name = "%02i" % i
                _winreg.DeleteValue(key, name)
            except EnvironmentError:
                break
        key.Close()

    def GetRegistryEntrys(self, folder, testExistence=False):
        path = "%s\%s" % (self.winregPath, folder)
        key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, path)
        c = 0
        entrys = []
        while 1:
            try:
                name, entry, v_type = _winreg.EnumValue(key, c)
                entry = entry.encode("iso-8859-1")
                if testExistence:
                    if os.path.exists(entry):
                        entrys.append(entry)
                else:
                    entrys.append(entry)
                c += 1
            except EnvironmentError:
                break
        key.Close()
        return entrys
Mit SetRegistryEntrys() schreibe ich Pfade in die registry. Mit GetRegistryEntrys() lese ich diese Pfade wieder. Da sie mir dabei als unicode strings zurückgegeben werden, konvertiere ich in momentan mein internes Encoding.
Bei manchen Zeichen erscheint dann folgender Fehler:

Code: Alles auswählen

File "PathDialog.py", line 1268, in GetRegistryEntrys
    entry = entry.encode("iso-8859-1")
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 78: ordinal not in range(256)
Verwende ich anstatt "iso-8859-1" sys.getfilesystemencoding() funktioniert es. Wenn aber ich in meinem Programm nur mit Unicode arbeite, müßte ich nichts codieren, oder?
BlackJack hat geschrieben:Welche Kodierung der Quelltext hat ist egal solange: a) der coding-Kommentar mit der tatsächlichen Kodierung übereinstimmt und man b) keine Zeichen ausserhalb von ASCII in normalen Zeichenketten verwendet. Der coding-Kommentar sagt Python "nur" welche Kodierung zum dekodieren von literalen Unicode-Zeichenketten im Quelltext verwendet werden soll.
Wenn ich folgendes "Programm" ausführe:

Code: Alles auswählen

# -*- coding: utf-8 -*-

print u"äöüß"
erhalte ich die Meldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print u"äöüß"
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
Ich frage mich warum, wenn die Zeichen doch in UTF-8 enthalten seien sollten?

Als Editor verwende ich übrigens "Scite". Kann es auch daran liegen? Wie finde ich heraus in welchen Encoding die Datei vom Editor abgespeichert wird? Welche Rolle spielt der Editor bei der ganzen Encoding-Geschichte?

Ich weiß: viele, viele Fragen, manche vielleicht auch überflüssig, aber das weiß man als Fragesteller auch meist nur nach der Antwort. :cry:
Deswegen schon mal vielen Dank für die Mühe!


@Jens: Ich bin gerade dabei deinen Link durchzuforsten. Danke!
Gruß, Harry
BlackJack

HarryH hat geschrieben:
BlackJack hat geschrieben:Wenn Du Dich schon mit Unicode auseinandersetzt, dann sollte die "interne" Kodierung gar keine sein, sondern es sollten soweit es möglich ist Unicode-Zeichenketten verwendet werden und nur an den "Ein-" und "Ausgängen" entsprechende Kodierungen vorgenommen werden.
Was meinst du hier mit 'interne' Codierung? Ich meinte damit den speziellen Kommentar in der ersten Zeile der Datei.
Ich weiss das ist immer blöd anderen Leuten zu sagen was sie meinen, als ob sie das selber nicht wüssten, aber auch in dem Beitrag auf den ich gerade antworte meinst Du mit interner Kodierung nicht den speziellen Kommentar, sondern die Kodierung in die Du Unicode-Zeichenketten umwandlest die aus der Registry in Dein Programm kommen, bzw. dieses wieder Richtung Registry verlassen. So beschreibst Du das jedenfalls.
Unicode-Zeichenketten werden mit 'u' vor dem String bezeichnet, oder?
Habe ich das richtig verstanden, der spezielle Kommentar gilt nur für die Zeichen die ich in meinen Quelltext schreibe?
Ja genau.
Woher weiß ich eigentlich in welcher Codierung mein Editor speichert?
Das sollte Dir der Editor irgendwo anzeigen. Zum Beispiel in einem Untermenü wo man die Kodierungseinstellung ändern kann, oder im Laden/Speichern-Dialog.
Mit SetRegistryEntrys() schreibe ich Pfade in die registry. Mit GetRegistryEntrys() lese ich diese Pfade wieder. Da sie mir dabei als unicode strings zurückgegeben werden, konvertiere ich in momentan mein internes Encoding.
Hier benutzt Du die Bezeichnung "internes Encoding". Und hier stellt sich die Frage: Warum? Wenn die Registry Unicode liefert, werden die Funktionen zum setzen sicher auch Unicode entgegennehmen.
Wenn ich folgendes "Programm" ausführe:

Code: Alles auswählen

# -*- coding: utf-8 -*-

print u"äöüß"
erhalte ich die Meldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print u"äöüß"
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
Ich frage mich warum, wenn die Zeichen doch in UTF-8 enthalten seien sollten?
Mach mal aus dem ``print`` ein ``blah =``, dann gibt es keine Fehlermeldung. Das Problem ist nicht aus dem Quelltext ein Unicode-Objekt zu machen, also die Bytes im Quelltext zu *dekodieren*. In der Zeile soll das Unicode-Objekt ausgegeben werden und dazu muss man es wieder in Bytes umwandeln. Und wenn Python nicht herausfinden kann, welche Kodierung die Datei wohin ausgegeben wird, erwartet, dann wird ASCII verwendet. Und die Umlaute und das 'ß' gibt's in ASCII nicht. Das gibt dann den Unicode*Encode*Error.
Antworten