Python,gettext:如何为模块级和类级变量获取正确的语言环境?



当我将gettext用于模块级和类级变量时,我遇到了一些麻烦。

首先,在导入时,我使用默认语言环境并安装它。 之后,当我通过解析设置开始使用项目并使用gettext.translation.install设置正确的语言环境时,我会获得特定的语言环境。一切正常,但在我的代码中,所有模块级和类级变量都保持默认语言环境的翻译,而不是正确的。

例如,我有这样的项目:

├── foo.py
├── i18t
│   └── __init__.py
├── __init__.py
└── run.py

i18t/__init__.py包含:

import gettext
from os import path
SUPPORTED_LANGUAGES = ('en', 'fr')
DEFAULT_LANGUAGE = SUPPORTED_LANGUAGES[0]
locale_path = path.abspath(path.join(path.dirname(__file__), 'locale'))
TRANSLATIONS = {
lang: gettext.translation(
'domain',
locale_path,
languages=[lang]
) for lang in SUPPORTED_LANGUAGES
}

def install_language(language):
lang = TRANSLATIONS.get(language)
if lang is None:
lang = TRANSLATIONS[DEFAULT_LANGUAGE]
lang.install()

__init__.py

from i18n import DEFAULT_LANGUAGE, install_language
install_language(DEFAULT_LANGUAGE)

foo.py

foo = _('Bar')

run.py

from i18t import install_language
import foo

def main():
...
read config and get right locale
...
install_language(right_locale)
bar = _('Bazz')
print(foo.foo)
print(bar)

我执行run.py,我得到foo.foo默认区域设置的翻译和bar正确的区域设置。 我知道foo.foo导入模块时只能运行一次_(gettext(,但我需要获得正确的翻译字符串。 哪种更好的方法可以做到这一点?

这种情况的问题是希望对在导入时仅计算一次的字符串使用运行时函数gettext。我认为最好不要这样做。

但是我通过使用类似字符串的对象解决了这个问题,例如在 speaklater 包或继承对象 UserSting 中并制作自己的gettext函数:

from collections import UserString

class RuntimeTranslatedString(UserString):
def __init__(self, message):
self._data = message
@property
def data(self):
return _(self._data)

def N_(message):
return RuntimeTranslatedString(message)

在你的代码中,你可以像_(gettext(一样使用它:

from .i18n import N_
foo = N_('Bar')

不要忘记将其添加到您的extract_message命令中。在我的setup.cfg中,它看起来像:

[extract_messages]
output_file = my-package/i18n/locale/translation.pot
keywords = _ N_

我不确定这是否是好的解决方案,但它有效。

最新更新