如何在您的应用程序或库中使用 oslo.i18n¶
安装¶
在命令行
$ pip install oslo.i18n
创建集成模块¶
要在项目中使用 oslo.i18n(例如 myapp),您需要创建一个小的集成模块来保存 TranslatorFactory 的实例以及工厂创建的标记函数引用。
注意
库可能不希望将新的集成模块作为其公共 API 的一部分公开,因此,与其将其命名为 myapp.i18n,不如将其命名为 myapp._i18n,以表明它是一个私有实现细节,不应在库自身代码之外使用。
注意
从 Pike 系列开始,OpenStack 不再支持日志翻译。无需在新代码中添加翻译说明,并且可以从旧代码中删除这些说明。有关更多详细信息,请参阅邮件列表上的邮件线程 理解日志域更改 openstack-dev。
# myapp/_i18n.py
import oslo_i18n
DOMAIN = "myapp"
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
# The primary translation function using the well-known name "_"
_ = _translators.primary
# The contextual translation function using the name "_C"
# requires oslo.i18n >=2.1.0
_C = _translators.contextual_form
# The plural translation function using the name "_P"
# requires oslo.i18n >=2.1.0
_P = _translators.plural_form
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)
然后,在您的代码的其余部分,为每个消息使用适当的标记函数
from myapp._i18n import _
# ...
variable = "openstack"
some_object.name_msg = _('my name is: %s') % variable
# ...
try:
# ...
except AnException1:
# Log only, log messages are no longer translated
LOG.exception('exception message')
except AnException2:
# Raise only
raise RuntimeError(_('exception message'))
else:
# Log and Raise
msg = _('Unexpected error message')
LOG.exception(msg)
raise RuntimeError(msg)
注意
在 _i18n 中导入多个模块的单行代码是 OpenStack 风格指南 中导入语句的一个有效例外。
使用标记函数(例如 _)非常重要,而不是名称的较长形式,因为扫描源代码以查找可翻译字符串的工具会查找标记函数名称。
警告
在内置命名空间中安装 _() 的旧方法已被弃用。修改全局命名空间会影响库以及应用程序,因此可能会干扰正确的消息目录查找。对 gettextutils.install() 的调用应替换为此处描述的应用程序或库集成模块。
处理对导入的 Hacking 反对¶
OpenStack 风格指南 倾向于导入模块并在导入后从这些模块访问名称,而不是直接导入名称。例如
# WRONG
from foo import bar
bar()
# RIGHT
import foo
foo.bar()
linting 工具 hacking 通常会抱怨从模块内导入名称。可以接受绕过对翻译标记函数的检查,因为它们必须具有特定的名称,并且其使用模式由消息目录提取工具而不是我们的风格指南决定。要绕过此集成模块导入的 hacking 检查,请在 tox.ini 中添加导入异常。
例如
# tox.ini
[hacking]
import_exceptions = myapp._i18n
延迟翻译¶
延迟翻译会尽可能延迟将消息字符串转换为翻译形式,包括如果消息未记录或以其他方式传递给用户,则可能永远不会转换。它还支持通过配置单独的日志处理程序来记录多种语言的翻译消息。
延迟翻译是通过从翻译函数返回一个特殊对象来实现的,而不是 Unicode 字符串。该特殊消息对象支持某些,但不是全部,字符串操作 API。例如,不支持使用加法进行连接,但支持变量插值。根据翻译字符串在应用程序中的使用方式,这些限制可能意味着无法使用延迟翻译,因此默认情况下未启用它。
要启用延迟翻译,请调用 enable_lazy()。
import oslo_i18n
oslo_i18n.enable_lazy()
翻译消息¶
使用 translate() 将字符串翻译为特定语言环境。 translate() 处理延迟翻译和已经立即翻译的字符串。它应在已知要使用的语言环境的点使用,通常是在将消息返回或发出日志消息之前。
import oslo_i18n
trans_msg = oslo_i18n.translate(msg, my_locale)
如果未指定语言环境,则使用默认语言环境。
可用语言¶
只有提供翻译的语言才可用于翻译。要确定可用的语言,提供了 get_available_languages()。
import myapp._i18n
languages = myapp._i18n.get_available_languages()
显示翻译的消息¶
需要进行一些准备才能在正在运行的应用程序中显示翻译的消息。
- 首选语言
您需要通过环境变量指定首选语言。可以通过
LANGUAGE、LC_ALL、LC_MESSAGES或LANGUAGE(前者具有优先级)指定首选语言。oslo_i18n.translate()可用于翻译字符串以覆盖首选语言。注意
您需要使用
enable_lazy()通过使用oslo_i18n.translate()覆盖首选语言。- 语言环境目录
Python
gettext使用路径<localedir>/<language>/LC_MESSAGES/<domain>.mo查找给定域的二进制mo文件。默认语言环境目录因发行版而异,并且在大多数情况下为/usr/share/locale。如果将消息目录存储在不同的位置,您需要通过名为
<DOMAIN>_LOCALEDIR的环境变量指定位置,其中<DOMAIN>是一个大写域名称,用-替换_和.。例如,对于域neutron使用NEUTRON_LOCALEDIR,对于域oslo_i18n使用OSLO_I18N_LOCALEDIR。注意
当您通过
<DOMAIN>_LOCALEDIR环境变量指定语言环境目录时,需要为每个域指定一个环境变量。更具体地说,如果您的应用程序使用域myapp` 使用 oslo.policy, 您 需要 指定 ``MYAPP_LOCALEDIR和OSLO_POLICY_LOCALEDIR,以确保显示来自您的应用程序和 oslo.policy 的翻译消息。