Internacionalización de programas Python

La internacionalización de programas permite que estos puedan ser entendidos por personas que hablan idiomas diferentes.

En este artículo enseño cómo internacionalizar un programa escrito en Python 3. Para este propósito se suele utilizar el módulo gettext, que esta incluido en Python.

Antes de nada, debemos tener un programa para poder traducirlo. Vamos a traducir el siguiente programa llamado saluda.py:

#!/usr/bin/env python3

nombre = input('¿Cómo te llamas? ')
print('Hola, {}.'.format(nombre))

El programa es muy sencillo. Pregunta al usuario su nombre y le saluda por su nombre o, mejor dicho, le vuelve a repetir lo que el usuario ha escrito.

Para internacionalizar el programa anterior vamos a importar el módulo gettext y a ejecutar la función install de gettext. Después, debemos rodear el texto que queramos traducir con _(), es decir, si queremos traducir 'texto' escribiremos _('texto').

#!/usr/bin/env python3

import gettext

gettext.install('saluda', 'locale')

nombre = input(_('¿Cómo te llamas? '))
print(_('Hola, {}.').format(nombre))

Ahora creamos el directorio locale, donde guardaremos las traducciones:

mkdir locale

Después debemos ejecutar pygettext, que viene instalado con Python. Quizás debéis ejecutar pygettext3 para indicar que queréis trabajar con Python 3:

pygettext -d saluda -p locale saluda.py

Yo lo hice así desde la terminal:

Ejecutando pygettext

Ahora tenemos el archivo saluda.pot en el directorio locale. Para trabajar con archivos de traducción es recomendable usar un editor preparado para dicha tarea, porque hacerlo a mano es muy tedioso. Podemos usar el editor Poedit o cualquier otro editor diseñado para traducir.

Si vamos a utilizar Poedit seleccionamos Archivo>Nueva desde archivo POT/PO y seleccionamos el archivo saluda.pot. A continuación, debemos seleccionar el idioma al que queremos traducir, yo voy a elegir el alemán.

Seleccionando idioma para traducción con Poedit

Cuando terminemos la traducción, debemos guardarla:

Guardando traducción con Poedit

Se generarán dos archivos: de.po y de.mo. El archivo de.po es legible por los humanos y el archivo de.mo es legible por la máquina. El archivo de.mo debe guardarse según la siguiente estructura de ficheros: locale/de/LC_MESSAGES/de.mo. Para que no tengamos que acordarnos de la anterior estructura cada vez que creemos o actualicemos una traducción, podemos ubicar el siguiente programa en el directorio locale y ejecutarlo cada vez que actualicemos un archivo .po:

#!/usr/bin/env python3
# Copyright (C) 2016 Julie Marchant <onpon4@riseup.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import subprocess

if __name__ == "__main__":
    for fname in os.listdir():
        root, ext = os.path.splitext(fname)
        if ext == ".po":
            print("Generando {}...".format(fname))
            d, root = os.path.split(root)
            os.makedirs(os.path.join(d, root, "LC_MESSAGES"), exist_ok=True)
            oname = os.path.join(d, root, "LC_MESSAGES", "saluda.mo")
            subprocess.call(["msgfmt", "-o", oname, fname])

    print("Terminado.")

Tras ejecutar el anterior programa, ya tendremos los archivos de traducción donde corresponden. Al ejecutar saluda.py se utilizará el idioma por defecto del sistema operativo que lo ejecute. Es decir, si estamos utilizando el alemán como el idioma predeterminado del sistema operativo, el programa se ejecutará en alemán. Podemos comprobar si funciona para este idioma cambiando la variable de entorno LANGUAGE en el caso de que estemos trabajando con GNU/Linux. Se puede probar así:

Programa internacionalizado

Comentarios