"Internationalisierung" von Python-Programmen/Modu

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
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Hallo,
muß mein Programm sprachmäßig internationalisieren (d.h. User soll Sprache auswählen können).

In der Python Library Reference werden unter http://www.python.org/doc/current/lib/m ... ttext.html entsprechende Funktionen hierfür vorgestellt. Dort ist die Rede von "binary .mo files", in denen wohl nach der entsprechenden Übersetzung des jeweiligen Wortes gesucht wird. Leider sagen mir diese "Files" überhaupt nichts. Ich vermute jedoch, dass ich mir für jede mögliche Sprachauswahl wohl eine dieser .mo-files mit den entsprechenden Übersetzungen basteln muß?!? Wie müssen diese aufgebaut sein???
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hmm, auf mo dateien stoest man oefter, aber wie du sesbst sagtest sind sie binaer, dh, das du keine mo dateien schreiben kannst.
Schau dir das an
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi Ibuega,

die *.mo-Files kannst Du mit poEdit aus den mit pygettext erzeugten *.pot-Files erzeugen und bearbeiten.


Gruß

Dookie
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Genau das war die Info die ich benötigt habe; dass man mit pygettext.py *.pot -Files bekommt, diese nach dem Zufügen der Übersetzungen als *.po speichern muß und anschließend daraus mit msgfmt.py *.mo -Dateien generieren läßt...

Doch wie functioniert nun noch die die Einbindung in mein Programm: mit find(...) oder bindtextdomain(...) ?!? Wofür steht da "domain" und wie ändere ich dann noch die Sprachauswahl?!?
Fragen über Fragen... und ich schwitz schon ohne überhaupt was zu tun. Meine Unix-büchse hört sich auch an wie mein Staubsauger sonst nicht... und Sauna gibts inklusive...
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

das steht sehr schön hier: http://www.python.org/doc/current/lib/node274.html und auf den folgenden Seiten.

Normalerweise Braucht die Sprache nicht eingestellt zu werden, gettext ist so schlau die im System eingestellte Sprache zu verwenden, zumindest unter Linux, habs auf Windows noch nicht getestet. ansonsten findest Du unter dem Link auch wie mann die Sprache umstellen kann.


Gruß

Dookie
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Danke für dei schnelle Antwort.
mmh, d.h. dass gettext immer nur die im System eingestellte Sprache nimmt? Aber ich muß in meinem Programm vom Anwender auswählen können, welche Sprache er nutzen möchte. Geht das dann so nicht?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Gast

ja, hab ich auch schon probiert, aber da gibts ne Fehlermeldung, dass translation() mehr braucht wie nur dieses eine Keyword (languages=...
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

jo is wohl ein fehler in der Dokumentation, pydoc zeigt, daß translation noch die domain braucht, das sollte der Programmname ohne .py sein, unter dem dann auch die *.mo datei zu finden ist, also Beispiel für Test.py dann Test.mo und als Domain Test.


Gruß

Dookie
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Danke Dookie, das hat wieder etwas mehr Verständnis gebracht. (was ist mit Deinem Bild passiert?)

Leider funktioniert es immer noch nicht. Es wird die Übersetzungsdatei für die Domäne (Programm/Übersetzungsdateinamen ohne Endung) nicht gefunden und das obwohl ich für "localedir" den kompletten Pfad angegeben habe unter der die .mo-Datei liegt.

am besten ich geb mal den quellcode an:

Code: Alles auswählen

import gettext
from Tkinter import *

#importieren der eigenen Module:
import wertbearb, menubefehl, design

#############################
# Für Übersetzungsfunktion
_ = gettext.gettext
gettext.find('g09_gui', '/users/gcadc30/PO/WORK/') ###brauch ich das überhaupt?
gettext.install('g09_gui', '/users/gcadc30/PO/WORK/') ###brauch ich das überhaupt?

#nachstehende Zeile bringt die Fehlermeldung:
lang2 = gettext.translation('g09_gui', '/users/gcadc30/PO/WORK/', languages=['en']) ###woher kennt er das "en" eigentlich? 

lang2.install('g09_gui', '/users/gcadc30/PO/WORK/')
[...]
Außerdem verstehe ich noch nicht, wie dann unterschiedliche Sprachen in der mo.-Datei unterschieden werden wenn ich die Übersetzungsdatei genauso nennen muß wie das Programm. Dachte es gibt dann ne "english.mo" "german.mo" usw.?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

für jede Sprache gibts dann ein Verzeichnis mit den *.mo Dateien. Am Einfachsten legst Du ein Verzeichnis locale mit den Unterverzeichnissen de, en, fr, ... an. Dort hinein kommen die entsprechenden *.mo Dateien.
Hier mal ein kleines Hallo_Welt:

Code: Alles auswählen

import gettext
gettext.install('hello_world')
lang1 = gettext.translation('hello_world', 'locale', languages=['en'])
_ = lang1.gettext

print _("Hello World")
Gruß

Dookie
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

in die Verzeichnisse für die jeweilige Sprache kommt jeweils ein Verzeichnis "LC_MESSAGES" und da hinein die *.mo Dateien.
lbuega
User
Beiträge: 75
Registriert: Dienstag 15. April 2003, 08:51
Wohnort: Weissach

Uff, endlich... mit Dookies Beispiel (zwei weiter oben) funktioniert es nun:

Der Verzeichnis-Aufbau muss dafür folgendermaßen sein:
locale/en/LC_MESSAGES/ProgrammName.mo - Wobei locale ein beliebiger Name sein darf (muß halt dann auch im Programm entsprechend angegeben weren); aber en (bzw. "fr", "de" etc.) und LC_MESSAGES muß so geschrieben sein (klein, bzw. groß)!

Die entsprechende mit msgfmt.py generierte *.mo Übersetzungsdatei muß dann den selben Namen haben wie die Datei (Programm/Modul) von dem die Übersetzung ist.
Hoffe dies hilft anderen etwas Zeit und Nerven zu sparen...

An dieser Stelle noch mal herzlichen Dank an Dookie! :D
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

noch eine kleine Anmerkung:

die *.mo kann einen Beliebigen Namen haben. Der Name vor dem .mo wird dann in den Gettext-Funktionen/Methoden als Domain bezeichnet. Für Consoleausgaben hat sich da messages.mo durchgesetzt, für Fehlermeldungen errors.mo ... Der Vorteil von einer Programmname.mo besteht darin, das nur diese eine Datei für die verschiedenen Sprachen übersetzt werden muss und mehrfach gebrauchte gleichlautende Texte nur einmal in der Datei stehen.


Gruß

Dookie
xturbo77
User
Beiträge: 39
Registriert: Montag 9. September 2002, 20:05
Kontaktdaten:

Habe alles nach dieser Anleitung gemacht, bekomme aber letzendlich einen Fehler:

Code: Alles auswählen

lang1 = gettext.translation('messages', 'lang', languages=['de'])
  File "C:\WebDev\python23\lib\gettext.py", line 416, in translation
    t = _translations.setdefault(key, class_(open(mofile, 'rb')))
  File "C:\WebDev\python23\lib\gettext.py", line 176, in __init__
    self._parse(fp)
  File "C:\WebDev\python23\lib\gettext.py", line 304, in _parse
    tmsg = unicode(tmsg, self._charset)
LookupError: unknown encoding: CHARSET
Weiß jemand Rat :?:
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi xturbo77,

Du hast wohl vergessen in poEdit die Zeichenkodierung zu setzten? Schau mal ins *.po dort sollten zwei Zeilen stehen

Code: Alles auswählen

"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
ändere diese in

Code: Alles auswählen

"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
oder ergänze die Eintragungen mit poEdit und lass ein neues *.mo erzeugen.


Gruß

Dookie
xturbo77
User
Beiträge: 39
Registriert: Montag 9. September 2002, 20:05
Kontaktdaten:

Tausenddank.

PoEdit hab ich garnicht verwendet, wollte einfach mal kurz die Mehrsprachentauglichkeit von Python testen :) klappt echt super!
sacro_thaan
User
Beiträge: 12
Registriert: Montag 23. Januar 2006, 03:21

Hallo,

da ich auch gerade am arbeiten mit gettext bin, habe ich mal einen alten Threat rausgekramt, weil ich noch ein Problem habe.

Das oben beschriebene Problem mit charset ist durch den Tipp gelöst, aber jetzt habe ich folgenden Fehler:

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 81-83: invalid data

mein Header sieht so aus:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2006-05-19 04:08+Westeuropäische Normalzeit\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"

Woran liegt das jetzt? Umlaute im Text können es wohl nicht sein, da es auch mit der englischen Sprach-Datei passiert.

Der Code zum Einbinden von gettext sieht so aus:

Code: Alles auswählen

  gettext.install('App', './locale')
  presLan_en = gettext.translation('App', './locale', anguages=['en'])
  presLan_de = gettext.translation('App', './locale', languages=['de']) 
  self.presLan_en.install()
Gruß

Till
sacro_thaan
User
Beiträge: 12
Registriert: Montag 23. Januar 2006, 03:21

OK, hat sich erledigt, habe den Trick gefunden. iso-8859-1-codierung heißt das Zauberwort....

Sorry, hab es erst gefunden, nachdem ich gefragt habe

:oops:

Gruß

Till
Antworten