Allgemeine Lösung für Umlautprobleme?
Verfasst: Freitag 14. Juli 2006, 11:55
Hi!
Mich ärgert es immer wieder, wie umständlich man bei Python mit Umlauten umgehen muss. Überhaupt dann, wenn man Programme für Windows, Linux und Cygwin schreiben möchte UND diese eventuell auch mit cx_freeze oder py2exe packen möchte.
Dann gibt es noch die verschiedensten Editoren, Interpreter und IDEs in denen die Programme ja auch laufen sollten. (python, ipython, PyShell, IDLE, WingIDE,...)
Ich habe zwar den Hinweis bekommen, dass Python versucht, beim Schreiben in die Konsole das richtige Encoding zu verwenden wenn man einen Unicode-String übergibt, aber das funktioniert bei mir die meiste Zeit NICHT. Auf dieses anscheinend willkürliche Verhalten bei Unicode-Strings kann ich nicht setzen.
Deshalb habe ich mich mit einem Workaround befasst, der in den meisten Fällen funktionieren sollte. Allerdings ist dieser Ersatz ziemlich umständlich und ich kann ihn auch nicht überall testen. Aber zumindest habe ich es versucht.
Unten stehender Code wurde von mir bereits unter folgenden Bedingungen getestet:
- Windows 2000 - Python 2.4.3
- Windows 2000 - Python 2.4.3 - IDLE 1.1.3
- Windows 2000 - Python 2.4.3 - WingIDE 2.1.0-1
- Windows 2000 - Cygwin - Bash 3.0 - Python 2.4.1 (GCC)
- Windows 2000 - Cygwin - Bash 3.0 - Python 2.4.3 (MSC)
- Debian 3.1 Linux (locale: de_AT@euro) - Python 2.3.5
- Debian 3.1 Linux (locale: de_AT@euro) - Python 2.4.1
- Gentoo linux (local: de_AT.utf8) - Python 2.4.2 - (# -*- coding: utf-8 -*-)
Bitte probiert diesen Code mit eurem Betriebssystem aus und teilt mir mit, ob es damit Probleme gibt. Vielleicht weiß jemand auch eine bessere Lösung --> dann sagt sie mir. Bitte! Ich suche schon lange nach einer guten Lösung. Auch wenn ich mich damit blamiere, aber ich habe bis auf oben stehende Lösung noch nicht raus bekommen, wie man es besser machen könnte.
lg
Gerold
PS: Für sys.stderr habe ich noch überhaupt keine Lösung gefunden. Gibt es eine allgemein verwendbare Möglichkeit, das Encoding von sys.stderr raus zu bekommen?
- Edit: try-except um einen Import gelegt.
- Edit: Sonderfälle abgefangen
- Edit: .split("=")[1] hinzugefügt
- Edit: "POSIX" hinzugefügt
- Edit: auch für Linux ein sys.getfilesystemencoding() eingebaut
- Edit: "cygwin" raus geschmissen, da es von den Ausnahmefällen abgedeckt wird.
- Edit: Ab jetzt wird bei unbekannten Betriebsystemen zumindest versucht, das Encoding raus zu bekommen.
Mich ärgert es immer wieder, wie umständlich man bei Python mit Umlauten umgehen muss. Überhaupt dann, wenn man Programme für Windows, Linux und Cygwin schreiben möchte UND diese eventuell auch mit cx_freeze oder py2exe packen möchte.
Dann gibt es noch die verschiedensten Editoren, Interpreter und IDEs in denen die Programme ja auch laufen sollten. (python, ipython, PyShell, IDLE, WingIDE,...)
Ich habe zwar den Hinweis bekommen, dass Python versucht, beim Schreiben in die Konsole das richtige Encoding zu verwenden wenn man einen Unicode-String übergibt, aber das funktioniert bei mir die meiste Zeit NICHT. Auf dieses anscheinend willkürliche Verhalten bei Unicode-Strings kann ich nicht setzen.
Deshalb habe ich mich mit einem Workaround befasst, der in den meisten Fällen funktionieren sollte. Allerdings ist dieser Ersatz ziemlich umständlich und ich kann ihn auch nicht überall testen. Aber zumindest habe ich es versucht.
Unten stehender Code wurde von mir bereits unter folgenden Bedingungen getestet:
- Windows 2000 - Python 2.4.3
- Windows 2000 - Python 2.4.3 - IDLE 1.1.3
- Windows 2000 - Python 2.4.3 - WingIDE 2.1.0-1
- Windows 2000 - Cygwin - Bash 3.0 - Python 2.4.1 (GCC)
- Windows 2000 - Cygwin - Bash 3.0 - Python 2.4.3 (MSC)
- Debian 3.1 Linux (locale: de_AT@euro) - Python 2.3.5
- Debian 3.1 Linux (locale: de_AT@euro) - Python 2.4.1
- Gentoo linux (local: de_AT.utf8) - Python 2.4.2 - (# -*- coding: utf-8 -*-)
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# Lizenz: ohne Einschränkungen frei
import os
import sys
import codecs
# Imports für cx_freeze:
import encodings, encodings.ascii, encodings.utf_8, \
encodings.iso8859_1, encodings.iso8859_15
try:
import encodings.mbcs, encodings.cp850
except:
pass
# sys.stdout umleiten, damit Umlaute korrekt angezeigt werden.
#(funktioniert auch mit Idle und cx_freeze)
out_enc = ""
if sys.platform.startswith("win"):
out_enc = getattr(sys.stdout, "encoding", None) or \
sys.getfilesystemencoding() or "cp850"
elif sys.platform.startswith("linux"):
out_enc = getattr(sys.stdout, "encoding", None) or \
sys.getfilesystemencoding() or \
os.popen("locale | grep 'LC_MESSAGES'").read().strip().split("=")[1]
else:
out_enc = getattr(sys.stdout, "encoding", None) or \
sys.getfilesystemencoding() or ""
if out_enc.upper() in ("", "ASCII", "US-ASCII", "ANSI_X3.4-1968", "POSIX"):
out_enc = "raw_unicode_escape"
sys.stdout = codecs.getwriter(out_enc)(sys.stdout)
if __name__ == "__main__":
# testen
print "out_enc:", out_enc
print u"printtest öäüß"
sys.stdout.write(u"stdouttest: äüöß\n")
lg
Gerold
PS: Für sys.stderr habe ich noch überhaupt keine Lösung gefunden. Gibt es eine allgemein verwendbare Möglichkeit, das Encoding von sys.stderr raus zu bekommen?
- Edit: try-except um einen Import gelegt.
- Edit: Sonderfälle abgefangen
- Edit: .split("=")[1] hinzugefügt
- Edit: "POSIX" hinzugefügt
- Edit: auch für Linux ein sys.getfilesystemencoding() eingebaut
- Edit: "cygwin" raus geschmissen, da es von den Ausnahmefällen abgedeckt wird.
- Edit: Ab jetzt wird bei unbekannten Betriebsystemen zumindest versucht, das Encoding raus zu bekommen.