ognibit-logo
Menu
  • Home
  • Chi Sono
  • Contatti
  • Servizi
  • Computer Science
  • Blog
  • Informativa sulla privacy
Menu
ognibit-logo

Python Multilingua con GetText

Posted on Ottobre 31, 2019Agosto 4, 2022 by omar

Mi è capitato recentemente di dover realizzare un piccolo programmino in python che fosse internazionalizzato, ossia che comunicasse nella lingua dell’utente. Nel mio caso in italiano e in inglese.

Python viene distribuito già con un modulo pensato per risolvere questo problema e che è presente nel mondo della programmazione C e C++ dai primi anni ’90: gettext.

GetText è presente nel mondo GNU da molto tempo e rappresenta una suite di programmi e API vastissime, che permettono la gestione ottimale delle traduzioni dei vari programmi. In questo breve articolo vedremo come utilizzare in modo minimale questo pacchetto.

Pyhton gettext module

Come detto, non serve installare nulla di aggiuntivo perchè python viene già fornito del modulo gettext nella standard library e fornisce addirittura delle utility per processare i file.

Senza andare troppo nello specifico, gettext funziona così:

  1. Inclusione e utilizzo delle API nel codice sorgente
  2. Estrazione dei testi da tradurre con pygettext in formato POT
  3. Traduzione manuale nei file PO
  4. Compilazione in linguaggio macchina dei PO in MO
  5. Collocamento ordinato in una struttura del filesystem

Oltre a questo, ci sono vari strumenti per gestire ogni fase e, in particolar modo, fondere (merge) traduzioni precedenti con quelle nuove dovute allo sviluppo di nuovi componenti nei sorgenti. In questo articolo ci concentreremo solo sui cinque punti elencati.

Python API gettext

Per prima cosa, nei moduli che ci interessa tradurre, è necessario importare il modulo gettext e inizializzarlo.

import gettext

try:
    lang_default = gettext.translation('domain', 'locales')
    lang_default.install()
    _ = lang_default.gettext
except:
    _ = gettext.gettext

print(_('This is a translatable string.'))

Utilizzare l’underscore come funzione gettext è una prassi consolidata e permette di essere molto snelli nell’uso nel codice. Se si prova ad eseguire il codice si vedrà semplicemente la stringa stampata a video.

Estrarre il POT

La seconda fase consiste nell’estrarre un file di testo denominato POT (Portable Object Template) che conterrà lo schema generato in automatico di tutte le frasi da tradurre. La struttura interna è intuitiva:

: main.py:14
 msgid "This is a translatable string."
 msgstr ""

In pratica si usa la stringa presente nel sorgente come identificativo e un’altra stringa che andrà a sostituirla. Quindi è possibile cambiare le frasi di default, solitamente in inglese, con altre frasi migliorate sempre in inglese, senza ricompilare il codice. Ma come si crea il file POT? Nelle librerie preinstallate di python si trova il programma pygettext e su linux è un programma direttamente eseguibile

pygettext3.6 -d domain -o domain.pot main.py

Il programma è ovviamente pensato per elaborare codice python. Con le opzioni indicate si va a creare il file di output domain.pot per il dominio domain.

Tradurre il PO

I file PO (Portable Object) sono banalmente una copia del file POT in cui si riempiono i campi msgstr con la traduzione di una lingua. Nel mio caso ho creato due file, uno per l’inglese e uno per l’italiano. La nomenclatura del file rimane la stessa, domain.po, sarà la sua collocazione a indicarne la lingua di riferimento. Lo vedremo tra qualche passaggio.

Il file PO, per piccoli script, può benissimo essere editato a mano, con un editor di testo qualsiasi. Il file può venire creato con l’utility msginit per valorizzare in modo dettagliato anche le meta informazioni, ma il risultato è comunque un file PO di testo semplice. Esistono anche programmi appositi che leggono e modificano i file PO, pensati per i traduttori non programmatori e che aiutano nel lavoro, come poEdit.

Compilazione in file MO

Una volta completato il lavoro di traduzione, i file devono essere compilati per venire installati nel programma. Per farlo si usa il programma msgfmt

msgfmt -o domain.mo domain.po

In questo modo si creano i file MO (Machine Object) che saranno effettivamente usati dal modulo gettext. Il nome del file è uguale per ogni lingua così da combaciare con la string ‘domain‘ presente il codice python. Ora creiamo la struttura dove piazzare questi file.

Struttura directory

Nel codice python di esempio uno dei parametri di traduzione è ‘locales‘. Esso identifica la cartella nella directory attuale nel quale cercare le traduzioni. Rimando alla documentazione ufficiale per impostare le directory di sistema o altro.

L’alberatura che andremo a creare è la seguente

locales
 ├── en
 │   └── LC_MESSAGES
 └── it
     └── LC_MESSAGES

I codici ‘en‘ e ‘it‘ vengono direttamente dall’ISO 639-1 ed è comunemente usata in informatica per indicare i vari linguaggi.

All’interno delle directory LC_MESSAGES andremo a collocare i file MO relativi alla lingua descritta dalla cartella parent. Da questo momento il programma può cambiare lingua. Per provarlo basta eseguire

LANGUAGE=it ; python3.6 main.py

Se tutto è stato fatto come si deve, vi apparirà il programma in italiano!

Articoli recenti

  • Python Multilingua con GetText
  • PyData Venice #0 @ ESC
  • Python CLI con Fire
  • Bumpversion – Come gestire le versioni del software
  • PyConX 2019 – Python a Firenze

Categorie

  • Artificial Intelligence
  • Conferenze
  • Data Scientist Tool
  • progetti
  • python
© 2023 Omar Rampado | Powered by Minimalist Blog WordPress Theme