Могу ли я вызвать и установить модуль gettext Python в библиотеке и модуль, использующий его одновременно?

StackOverflow https://stackoverflow.com/questions/246137

Вопрос

Я кодирую библиотеку, включающую текстовую обратную связь, которую мне нужно перевести.

Я поместил следующие строки в модуль _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 (), которая передает правильные аргументы для этого модуля, а затем импортирует это как '_' в каждый модуль, который хочет его использовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top