Python、gettext:如何为模块级和 class 级变量获取正确的语言环境?
Python, gettext: How to get right locale for module- and class-level variables?
当我将 gettext 用于模块级和 class 级变量时,我遇到了一些麻烦。
首先,在导入时我使用我的默认语言环境并安装它。
之后,当我通过解析设置并使用 gettext.translation.install
来设置正确的语言环境来启动我的项目时,我会获得特定的语言环境。一切正常,但在我的代码中,所有模块级和 class 级变量都使用默认语言环境进行翻译,不正确。
例如我有这样的项目:
├── 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 package or inherit object 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_
我不确定这是不是好的解决方案,但它确实有效。
当我将 gettext 用于模块级和 class 级变量时,我遇到了一些麻烦。
首先,在导入时我使用我的默认语言环境并安装它。
之后,当我通过解析设置并使用 gettext.translation.install
来设置正确的语言环境来启动我的项目时,我会获得特定的语言环境。一切正常,但在我的代码中,所有模块级和 class 级变量都使用默认语言环境进行翻译,不正确。
例如我有这样的项目:
├── 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 package or inherit object 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_
我不确定这是不是好的解决方案,但它确实有效。