gettext

The Python gettext module provides internationalization (I18N) and localization (L10N) services for your Python applications. It allows you to write programs in a way that supports multiple natural languages and local conventions by managing the translation of text strings.

Here’s a quick example:

Python
import gettext

locale_dir = "./locale"

gettext.bindtextdomain("app", locale_dir)
gettext.textdomain("app")

spanish = gettext.translation("app", locale_dir, languages=["es"])
spanish.install()
_ = spanish.gettext

print(_("Hello, World!"))  # Output: ¡Hola, Mundo!

For this example to work, you need to have a .po file under the LC_MESSAGES/ directory. This should be your project’s structure:

project/
├── app.py
└── locale/
    └── es/
        └── LC_MESSAGES/
            └── app.po

Then, you have to create a app.mo file alongside of app.po with the msgfmt app.po -o app.mo command.

Key Features

  • Provides tools for extracting translatable strings from your source code
  • Supports message catalog files for managing translations
  • Allows for runtime selection of language translations

Frequently Used Classes and Functions

Object Type Description
gettext.gettext() Function Translates a single string
gettext.translation() Function Loads a translation catalog for a given language
gettext.install() Function Installs the translation function into the built-in namespace
gettext.NullTranslations Class Provides the basic interface you can use to write your own specialized translation classes

Examples

Loading a specific language translation:

Python
>>> french = gettext.translation("app", locale_dir, languages=["fr"])
>>> french.install()
>>> print(_("Hello, World!"))
'Bonjour le monde!'

Common Use Cases

  • Translating user interface text in desktop applications
  • Localizing web applications to support multiple languages
  • Managing translations for command-line tools

Real-World Example

Suppose you have a Python application that needs to support both English, Spanish, French, and German. Here’s how you might set up the project’s directory:

project/
├── app.py
└── locale/
    ├── es/LC_MESSAGES/
    │   ├── app.po
    │   └── app.mo
    ├── fr/LC_MESSAGES/
    │   ├── app.po
    │   └── app.mo
    └── de/LC_MESSAGES/
        ├── app.po
        └── app.mo

You can click the Show/Hide toggle button below to check the content of your .po files:

Text
# Spanish translation for app
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Language: es\n"

msgid "Hello, World!"
msgstr "¡Hola, Mundo!"

msgid "Welcome to Real Python!"
msgstr "¡Bienvenido a Real Python!"
Text
# French translation for app
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Language: fr\n"

msgid "Hello, World!"
msgstr "Bonjour, le Monde!"

msgid "Welcome to Real Python!"
msgstr "Bienvenue à Real Python!"
Text
# German translation for app
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Language: de\n"

msgid "Hello, World!"
msgstr "Hallo, Welt!"

msgid "Welcome to Real Python!"
msgstr "Willkommen bei Real Python!"

Now, you can set up gettext and use the languages as desired:

Python
>>> import gettext

>>> locale_dir = "./locale"

>>> gettext.bindtextdomain("app", locale_dir)
>>> gettext.textdomain("app")

>>> def print_translations(language_code, language_name):
...     print(f"\n--- {language_name} ---")
...     translation = gettext.translation(
...         "app", locale_dir, languages=[language_code]
...     )
...     translation.install()
...     _ = translation.gettext
...     print(_("Hello, World!"))
...     print(_("Welcome to Real Python!"))
...

>>> print_translations("es", "Spanish")
--- Spanish ---
¡Hola, Mundo!
¡Bienvenido a Real Python!

>>> print_translations("fr", "French")
--- French ---
Bonjour, le Monde!
Bienvenue à Real Python!

>>> print_translations("de", "German")
--- German ---
Hallo, Welt!
Willkommen bei Real Python!