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

问题描述 投票:1回答:1

当我使用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),但我需要得到正确的翻译字符串。哪种更好的方法呢?

python gettext
1个回答
0
投票

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

但我解决了这个问题,使用类似于speaklater package的字符串对象或继承对象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_

我不确定这是一个很好的解决方案,但它确实有效。

© www.soinside.com 2019 - 2024. All rights reserved.