Posso chiamare e impostare il modulo gettext Python in una libreria e un modulo utilizzandolo contemporaneamente?
-
05-07-2019 - |
Domanda
Sto codificando una libreria che include un feedback testuale che devo tradurre.
Ho inserito le seguenti righe in un modulo _config.py che importa ovunque nella mia app:
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("messages", localdir)
Ho i file * .mo in ./locale/lang_LANG/LC_MESSAGES e applico la funzione _ () a tutte le stringhe che devono essere tradotte.
Ora ho appena aggiunto una funzione per l'utente, presumibilmente un programmatore, per essere in grado di creare i propri messaggi. Non voglio che si preoccupi dell'implementazione sottostante, quindi voglio che sia Apple per renderlo qualcosa di semplice come:
lib_object.message = "My message"
Ho usato le proprietà per renderlo pulito, ma cosa succede se il mio utente vuole tradurre il proprio codice (che utilizza il mio) e fa qualcosa del tipo:
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("user_app", localdir)
lib_object.message = _("My message")
È un problema? Cosa posso fare per evitare problemi senza disturbare il mio utente?
Soluzione
È possibile utilizzare l'API gettext basato sulla classe per isolare i cataloghi di messaggi. Questo è anche ciò che è raccomandato nella python gettext documentazione .
Lo svantaggio è che tu o l'altro sviluppatore dovrete usare il metodo gettext o definire il metodo _ ()
nell'ambito locale, associato alla specifica classe gettext. Un esempio di una classe con il proprio catalogo di stringhe:
import gettext
class MyClass(object):
def __init__(self, locale_for_instance):
self.lang = gettext.translation("appname", localedir, \
locale=locale_for_instance)
def some_method(self, arg):
return self.lang.gettext("You called some method")
def other_method(self, arg): # does the same thing
_ = self.lang.gettext
return _("You called some method")
Potresti applicare il codice per aggiungere _ ()
in un decoratore, quindi tutti i metodi che ne hanno bisogno sono preceduti da qualcosa come @with_local_gettext
(Nota, non ho testato quanto sopra, ma dovrebbe funzionare bene (tm))
Se l'obiettivo è quello di non disturbare il tuo utente (e non è molto bravo) credo che potresti usare l'approccio basato sulla classe nel tuo codice e consentire all'utente di usare quello globale.
Altri suggerimenti
Puoi solo gettext.install () una volta. In generale è inutile per il lavoro in biblioteca - gettext.install () farà la cosa giusta solo se il modulo che lo chiama è responsabile dell'intero programma, poiché ti fornirà un solo catalogo da cui caricare. Il codice della libreria dovrebbe fare qualcosa di simile a quello che fa Mailman: avere il proprio wrapper per gettext () che passa gli argomenti giusti per questo modulo, quindi lo importa come '_' in ogni modulo che vuole usarlo.