{"id":17475,"date":"2026-07-09T11:19:06","date_gmt":"2026-07-09T09:19:06","guid":{"rendered":"https:\/\/modilingua.com\/?p=17475"},"modified":"2026-07-09T11:19:06","modified_gmt":"2026-07-09T09:19:06","slug":"python-localization","status":"publish","type":"post","link":"https:\/\/modilingua.com\/de\/l10n-und-t9n\/anwendungen\/python-lokalisierung\/","title":{"rendered":"Eine Gettext-Checkliste f\u00fcr die Python-Lokalisierung"},"content":{"rendered":"<p class=\"p3 wp-block-paragraph\">Ist die jeweilige Python-Anwendung \u00fcberhaupt bereit f\u00fcr eine \u00dcbersetzung?<\/p>\n\n\n\n<p class=\"p3 wp-block-paragraph translation-block\">Bei der Lokalisierung kann das <code>gettext<\/code>-Modul helfen, aber es ist nicht in der Lage, unklaren Quellcode, vage Platzhalter, uneinheitliche Terminologie oder Produkttexte, die nur auf Englisch funktionieren, zu beheben. Bevor Zeichenfolgen also zur \u00dcbersetzung gesendet werden, muss die App einer grundlegenden Pr\u00fcfung hinsichtlich <a href=\"https:\/\/modilingua.com\/de\/l10n-und-t9n\/anwendungen\/software-internationalisierung\/\" data-type=\"post\" data-id=\"16964\" target=\"_self\">Software-Internationalisierung<\/a> und -Lokalisierung unterzogen werden. Andernfalls besteht die Gefahr, ein mehrsprachiges Produkt zu erstellen, das technisch zwar funktioniert, sich aber ungeschickt, uneinheitlich oder unvollst\u00e4ndig anf\u00fchlt.<\/p>\n\n\n\n<h2 id=\"what-the-python-gnu-gettext-module-does\" class=\"wp-block-heading\"><span class=\"s1\">Wof\u00fcr das gettext-Modul in Python zust\u00e4ndig ist<\/span><\/h2>\n\n\n\n<p class=\"p1 wp-block-paragraph\">In der <a href=\"https:\/\/docs.python.org\/3\/library\/gettext.html\" target=\"_blank\" rel=\"noopener\">Python-3-Dokumentation<\/a> wird <code>gettext<\/code> als Modul beschrieben, das Internationalisierungsfunktionen f\u00fcr Python-Module und -Anwendungen bereitstellt. In der Praxis erm\u00f6glicht das <code>gettext<\/code> -Modul einer Python-Anwendung, Meldungskataloge anstelle von fest codierten, f\u00fcr den Benutzer sichtbaren Zeichenfolgen zu verwenden.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph translation-block\">Ein typischer GNU-gettext-Workflow sieht so aus: Entwickler markieren die entsprechenden Strings im Quellcode, extrahieren sie in eine <code>.pot<\/code> -Datei, legen f\u00fcr jedes Locale eine eigene <code>.po<\/code>-Datei an und kompilieren die fertigen \u00dcbersetzungen anschlie\u00dfend in bin\u00e4re <code>.mo<\/code>-Dateien. Zur Laufzeit verwendet die Anwendung dann das aktuelle Locale oder einen ausgew\u00e4hlten Sprachcode, um die passende \u00dcbersetzung anzuzeigen.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Python unterst\u00fctzt dieses GNU-gettext-Modell \u00fcber die Standardbibliothek. Es ist nach wie vor ein g\u00e4ngiger Ansatz f\u00fcr Python i18n und l10n, besonders wenn man einen verl\u00e4sslichen <a href=\"https:\/\/modilingua.com\/de\/l10n-und-t9n\/anwendungen\/app-lokalisierung\/\" data-type=\"post\" data-id=\"15460\">Lokalisierungsprozess f\u00fcr Anwendungen<\/a>, Kommandozeilentools oder Python-Module braucht.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Gettext ist allerdings nur der technische Mechanismus. Der eigentliche Lokalisierungsablauf geht deutlich dar\u00fcber hinaus.<\/p>\n\n\n\n<h2 id=\"python-i18n-starts-in-the-source-code\" class=\"wp-block-heading\"><span class=\"s1\">Weshalb \u00dcbersetzungsprobleme meist im Code entstehen<\/span><\/h2>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Ein \u00dcbersetzungsprojekt beginnt also mit der Frage, ob die Originaltexte im Code \u00fcberhaupt f\u00fcr eine andere Sprache taugen.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph translation-block\">Nehmen wir eine Buchungsplattform als Beispiel. Eine Fehlermeldung wie \u201eAktion fehlgeschlagen\" erscheint im Code oft an zehn verschiedenen Stellen \u2013 bei einer abgelehnten Zahlung, einer abgelaufenen Sitzung, einem doppelten Buchungsversuch usw. Im Code selbst ist das kein Problem, weil der umgebende Kontext klar macht, welche der zehn Situationen gemeint ist. Ein \u00dcbersetzer sieht aber nur die isolierte Zeile in der <code>.po<\/code>-Datei und muss raten.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph translation-block\">\u00c4hnlich kritisch ist die Art, wie Werte in S\u00e4tze eingebaut werden. Ein Datum, das im Code als reiner Zahlenstring zusammengesetzt wird \u2013 etwa \u201e15\/03\/2026\" \u2013 funktioniert zwar in Sprachen mit Tag-Monat-Reihenfolge, kollidiert aber in einer Sprache, die zuerst das Jahr nennt. Solche Formatierungsentscheidungen geh\u00f6ren in die Locale-Logik, nicht in einen manuell gebauten String.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Zahlw\u00f6rter sind ein eigenes Kapitel. \u201e2 Zimmer verf\u00fcgbar\" und \u201e1 Zimmer verf\u00fcgbar\" brauchen in vielen Sprachen nicht zwei, sondern drei oder vier grammatische Formen \u2013 ein Umstand, den ein einzelner, hart codierter Satz niemals abbildet.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Wird das erst nach dem Export bemerkt, betrifft die Korrektur nicht mehr nur den Quellcode, sondern auch die bereits verteilten po-Dateien und jede \u00dcbersetzung, die auf Basis des alten, unklaren Strings schon entstanden ist. Der Katalog selbst zeigt diese M\u00e4ngel nicht an. Das l\u00e4sst sich nur vorher im Code pr\u00fcfen.<\/p>\n\n\n\n<h2 id=\"common-traps-when-you-localize-a-python-app\" class=\"wp-block-heading\"><span class=\"s1\">F\u00fcnf typische Probleme bei der Lokalisierung von Python-Anwendungen<\/span><\/h2>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Ein Klassiker ist das Zusammenkleben von Satzteilen im Code, etwa nach dem Muster \u201eIhre\" + anzahl + \u201eArtikel wurden versendet\". Solche Konstruktionen sind im Original meist unauff\u00e4llig, brechen aber in Sprachen mit anderer Wortstellung oder mit grammatischem Geschlecht regelrecht auseinander. Ein vollst\u00e4ndiger, in sich stehender Satz l\u00e4sst sich dagegen als Ganzes \u00fcbersetzen, ohne dass die \u00dcbersetzung von der Position eines eingef\u00fcgten Werts abh\u00e4ngt.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Ein zweites, oft \u00fcbersehenes Problem sind Texte au\u00dferhalb der sichtbaren Benutzeroberfl\u00e4che: automatische Best\u00e4tigungsmails, Push-Benachrichtigungen, Texte in PDF-Exporten oder Meldungen in Log-Dateien, die dem Nutzer versehentlich angezeigt werden. Ein Produkt kann in der Haupt-App makellos lokalisiert sein und trotzdem an jeder dieser Randstellen in die Ausgangssprache zur\u00fcckfallen.<\/p>\n\n\n\n<p class=\"p2 wp-block-paragraph translation-block\">Vage Platzhalter sind das dritte typische Problem. Ein Platzhalter wie <code>%s<\/code> sagt dem \u00dcbersetzer nichts. Benannte Platzhalter wie <code>{user_name}<\/code>, <code>{event_name}<\/code> or <code>{amount}<\/code> geben mehr Kontext und senken das Risiko fehlerhafter \u00dcbersetzungsdateien. Eine Python-Anwendung k\u00f6nnte zum Beispiel so eine nutzerseitige Meldung erzeugen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-background-secondary-background-color has-background\"><code>import gettext\n\n_ = gettext.gettext<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Variante ist schwieriger zu \u00fcbersetzen, weil der Platzhalter anonym ist:<\/p>\n\n\n\n<pre class=\"wp-block-code has-background-secondary-background-color has-background\"><code>message = _(\"%s wurde hinzugef\u00fcgt\") % item_name<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Der \u00dcbersetzer sieht nur\u00a0<code>%s wurde hinzugef\u00fcgt<\/code>. Er wei\u00df nicht, worauf sich\u00a0<code>%s<\/code>\u00a0bezieht, was genau hinzugef\u00fcgt wurde oder wo die Meldung \u00fcberhaupt erscheint.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Variante ist klarer, weil der Platzhalter benannt und der Satz vollst\u00e4ndig ist:<\/p>\n\n\n\n<pre class=\"wp-block-code has-background-secondary-background-color has-background\"><code>message = _(\"Produkt {product_name} wurde dem Warenkorb hinzugef\u00fcgt\").format(\n    product_name=product_name\n)<\/code><\/pre>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Der Unterschied ist keine Stilfrage. Bei benannten Platzhaltern kann eine \u00dcbersetzung die Reihenfolge frei anpassen, ohne dass die Werte an der falschen Stelle landen oder das Programm crasht, wenn ein Formatargument fehlt.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Viertens: nicht jeder String vertr\u00e4gt denselben Freigabeprozess. Ein Tooltip l\u00e4sst sich frei und sinngem\u00e4\u00df \u00fcbersetzen; eine Widerrufsbelehrung oder ein Preis\u00e4nderungshinweis eher nicht. L\u00e4uft beides durch dieselbe Pr\u00fcfschleife, f\u00fchrt das entweder zu unn\u00f6tiger Verz\u00f6gerung bei harmlosen Texten oder zu einer zu knappen Pr\u00fcfung bei rechtlich heiklen.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph translation-block\">F\u00fcnftens landen in vielen <code>.pot<\/code>-Dateien Zeilen, die dort nichts verloren haben: Platzhaltertexte aus der Entwicklung, auskommentierte alte Versionen einer Meldung, interne Debug-Ausgaben. Jede dieser Zeilen kostet das \u00dcbersetzungsteam Zeit und verw\u00e4ssert den \u00dcbersetzungsspeicher mit Eintr\u00e4gen, die nie im Produkt erscheinen.<\/p>\n\n\n\n<p class=\"p1 wp-block-paragraph\">So unterschiedlich diese f\u00fcnf Probleme auch klingen m\u00f6gen, im Kern sind sie gleich: Sie werden im gettext-Workflow sichtbar, entstehen aber schon vorher, beim Schreiben des Codes.<\/p>\n\n\n\n<h2 id=\"a-short-python-localization-checklist\" class=\"wp-block-heading\"><span class=\"s1\">Ein Vier-Punkte-Check vor dem ersten Export<\/span><\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/modilingua.com\/wp-content\/uploads\/python-l10n-checklist-1024x576.jpeg\" alt=\"python l10n checkliste\" class=\"wp-image-17476\" srcset=\"\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" data-srcset=\"\" \/><\/figure>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Es empfiehlt sich, vor der \u00dcbersetzung des Python-Quellcodes eine kurze \u00dcberpr\u00fcfung der Voraussetzungen durchzuf\u00fchren.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Textqualit\u00e4t im Code: Steht jeder \u00fcbersetzbare String f\u00fcr sich allein verst\u00e4ndlich da, ohne dass man den umgebenden Code kennen muss? Sind S\u00e4tze vollst\u00e4ndig statt zusammengeklebt, Platzhalter benannt statt anonym, und ist f\u00fcr jede Zahlenangabe eine Pluralregel vorgesehen?<\/li>\n\n\n\n<li>Locale- und Formatlogik: Woher wei\u00df die Anwendung, welche Sprache gilt, und was passiert, wenn diese Sprache fehlt? Werden Datum, Uhrzeit, Zahlenformat und W\u00e4hrung \u00fcber die Locale-Bibliothek erzeugt statt im Code manuell zusammengebaut?<\/li>\n\n\n\n<li class=\"translation-block\">Sauberkeit des Katalogs: Enth\u00e4lt die <code>pot<\/code>-Datei ausschlie\u00dflich Texte, die tats\u00e4chlich im Produkt erscheinen? Bekommt jeder Eintrag genug Kontext, damit ein \u00dcbersetzer nicht raten muss, und wird die fertige <code>mo<\/code>-Datei im echten Programmablauf getestet statt nur einzeln \u00fcberpr\u00fcft?<\/li>\n\n\n\n<li>Definition von \u201efertig\": Z\u00e4hlt eine \u00dcbersetzung schon als abgeschlossen, wenn alle Strings einen Eintrag im Katalog haben \u2013 oder erst, wenn Fehlermeldungen, Best\u00e4tigungen und kritische Entscheidungspunkte in der Zielsprache genauso klar funktionieren wie im Original?<\/li>\n<\/ul>\n\n\n\n<p class=\"p1 wp-block-paragraph\">Ein Programm, das <code>gettext<\/code> korrekt einbindet, ist noch kein <a href=\"https:\/\/modilingua.com\/de\/l10n-und-t9n\/anwendungen\/produkt-lokalisierung\/\" data-type=\"post\" data-id=\"17075\">lokalisiertes Produkt<\/a>. Das eine ist Technik, das andere ist Sorgfalt an vielen kleinen Stellen im Code. Wer diesen Unterschied vor dem ersten Export kl\u00e4rt, entscheidet damit auch, wie viele R\u00fcckfragen sp\u00e4ter vom \u00dcbersetzungsteam kommen.<\/p>","protected":false},"excerpt":{"rendered":"<p>In vielen Beitr\u00e4gen zu diesem Thema geht es um dieselben drei Schritte: gettext installieren, eine erste po-Datei anlegen, eine zweite Sprache zum Laufen bringen. Das ist nett, umgeht aber eine grundlegende Frage.<\/p>","protected":false},"author":3,"featured_media":17477,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"Python Localization: A Gettext Readiness Checklist","_seopress_titles_desc":"Python localization and i18n checklist for the gettext module, locale handling, source code and l10n readiness in a Python app.","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"python localization","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[],"_seopress_pro_schemas_manual":[],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"footnotes":""},"categories":[111],"tags":[],"class_list":["post-17475","post","type-post","status-publish","format-standard","has-post-thumbnail","category-applications"],"_links":{"self":[{"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/posts\/17475","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/comments?post=17475"}],"version-history":[{"count":7,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/posts\/17475\/revisions"}],"predecessor-version":[{"id":17557,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/posts\/17475\/revisions\/17557"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/media\/17477"}],"wp:attachment":[{"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/media?parent=17475"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/categories?post=17475"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/modilingua.com\/de\/wp-json\/wp\/v2\/tags?post=17475"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}