Могу ли я вызвать и установить модуль gettext Python в библиотеке и модуль, использующий его одновременно?
-
05-07-2019 - |
Вопрос
Я кодирую библиотеку, включающую текстовую обратную связь, которую мне нужно перевести.
Я поместил следующие строки в модуль _config.py, который я импортирую повсюду в моем приложении:
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("messages", localdir)
У меня есть файлы * .mo в ./locale/lang_LANG/LC_MESSAGES, и я применяю функцию _ () ко всем строкам, которые необходимо перевести.
Теперь я только добавил функцию для пользователя, предположительно программиста, чтобы он мог создавать свои собственные сообщения. Я не хочу, чтобы он заботился о реализации, лежащей в основе, поэтому я хочу, чтобы он был яблоком, чтобы сделать это как-то просто:
lib_object.message = "My message"
Я использовал свойства, чтобы сделать его чистым, но что, если мой пользователь хочет перевести свой собственный код (который использует мой) и делает что-то вроде:
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")
Это проблема? Что я могу сделать, чтобы избежать неприятностей, не беспокоя моего пользователя?
Решение
Вы можете использовать API-интерфейс gettext на основе классов для изоляции каталогов сообщений. Это также то, что рекомендуется в документации по gettext Python . р>
Недостатком является то, что вам или другому разработчику придется использовать метод gettext или определить метод _ ()
в локальной области, привязанной к определенному классу gettext. Пример класса с собственным каталогом строк:
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")
Вы можете прикрепить код для добавления _ ()
в декоратор, так что все методы, которым он нужен, имеют префикс типа @with_local_gettext
(обратите внимание, я не проверял выше, может, но это должно работать просто отлично (тм))
Если цель состоит в том, чтобы не беспокоить вашего пользователя (и он не очень хорош), я думаю, вы могли бы использовать подход на основе классов в своем коде и позволить пользователю использовать глобальный подход.
Другие советы
Вы можете получить gettext.install () только один раз. В целом, это бесполезно для работы библиотеки - gettext.install () будет делать то, что нужно, только если вызывающий модуль отвечает за всю программу, поскольку он предоставит вам только один каталог для загрузки. Код библиотеки должен делать что-то похожее на то, что делает Mailman: иметь свою собственную оболочку для gettext (), которая передает правильные аргументы для этого модуля, а затем импортирует это как '_' в каждый модуль, который хочет его использовать.