Eu posso chamar e definir o módulo gettext Python em uma biblioteca e um módulo de usá-lo ao mesmo tempo?
-
05-07-2019 - |
Pergunta
Im a codificação de uma biblioteca edifico gabarito textual que eu preciso traduzir.
Eu coloquei as seguintes linhas em um módulo _config.py que eu importar em todos os lugares em meu aplicativo:
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("messages", localdir)
Eu tenho os arquivos * .mo em ./locale/lang_LANG/LC_MESSAGES e eu aplicar a função _ () para todas as cordas que precisam ser traduzidos.
Agora eu só adicionou um recurso para o usuário, supostamente um programador, para ser capaz de criar suas próprias mensagens. Eu não quero que ele se preocupa com a implementação subjacente, então eu quero que ele seja maçã para fazer algo simples como:
lib_object.message = "My message"
Eu costumava propriedades para torná-lo limpo, mas o que se o meu o que é usuário de traduzir seu próprio código (que utiliza minas) e faz algo como:
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")
É um problema? O que posso fazer para problemas Evitar sem incomodar meu usuário?
Solução
Você pode usar a classe base api gettext para catálogos de mensagens isoladas. Este é também o que é recomendado no python gettext documentação .
A desvantagem é que você, ou o outro dev, terá que usar o método gettext ou definir o método _()
no âmbito local, vinculado à classe específica gettext. Um exemplo de uma classe com seu próprio catálogo string:
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")
Você poderia furar o código para adicionar o _()
em um decorador, então todos os métodos que precisam dele é prefixado com algo como @with_local_gettext
(Note, eu não testou o acima poderia, mas Ele deve funcionar muito bem (tm))
Se o objetivo é não incomodar o seu usuário (e ele não é muito bom) Eu acho que você poderia usar a abordagem baseada classe em seu código e deixar o usuário usar o global.
Outras dicas
Você só pode gettext.install () uma vez. Em geral, é inútil para o trabalho da biblioteca - gettext.install () só vai fazer a coisa certa se o módulo chamado é responsável por todo o programa, uma vez que só irá fornecer-lhe um catálogo de carga a partir. código da biblioteca deve fazer algo semelhante ao que Mailman faz:. têm seu próprio wrapper para gettext () que passa os argumentos certos para este módulo, em seguida, as importações que, como '_' em cada módulo que queira usá-lo