研究了一下 openstack中的本地化;主要使用gettext模块;
其中本地化包括对一般字符串的本地化和log的本地化;
(1)
_localedir = os.environ.get('essential'.upper() + '_LOCALEDIR')
_t = gettext.translation('essential', localedir=_localedir, fallback=True)
def _(msg):
if USE_LAZY:
return Message(msg, domain='essential')
else:
if six.PY3:
return _t.gettext(msg)
return _t.ugettext(msg)
这个就是字符串本地化函数 _(),只不过openstack中有多一了一个USE_LAZY变量;是延迟翻译的意思;如果延迟翻译,返回的是Message类;
Message 是一个继承于six.text_type的类,是一个unicode object。可以调用Message中的translate()方法他进行翻译;
(2)
下面是对log的本地化
_t_log_levels = dict(
(level, gettext.translation('essential' + '-log-' + level,
localedir=_localedir,
fallback=True))
for level in ['info', 'warning', 'error', 'critical']
)
每一个级别的log都有自己的domain
_log_translation(msg, level):
"""Build a single translation of a log message
"""
if USE_LAZY:
return Message(msg, domain='essential' + '-log-' + level)
else:
translator = _t_log_levels[level]
if six.PY3:
return translator.gettext(msg)
return translator.ugettext(msg)
为了方便使用,封装了下面的方法:
_LI = functools.partial(_log_translation, level='info')
_LW = functools.partial(_log_translation, level='warning')
_LE = functools.partial(_log_translation, level='error')
_LC = functools.partial(_log_translation, level='critical')
(3)
还有一个install()方法,
if lazy:
def _lazy_gettext(msg):
"""Create and return a Message object.
return Message(msg, domain=domain)
from six import moves
moves.builtins.__dict__['_'] = _lazy_gettext
else:
localedir = '%s_LOCALEDIR' % domain.upper()
if six.PY3:
gettext.install(domain,
localedir=os.environ.get(localedir))
else:
gettext.install(domain,
localedir=os.environ.get(localedir),
unicode=True)
其作用是在__builtins__中加入_(),这样你的应用中的各个模块都可以使用到_()方法。不过这样影响比较大,局部的模块最好别使用install()方法,而是用类似下面的方式来做
import gettext
t = gettext.translation('mymodule', ...)
t = gettext.translation('mymodule', ...)
_ = t.gettext
(4)
在这个模块中还有一个translateHandler,是为log准备的。可以在打log的时候,对log进行翻译;