Python 国际化(i18n) 支持

python使用gettext来实现i18n支持。具体参数信息请看gettext
module帮助。

python中对于国际化的字符串,只需要外加_()即可。

如: print(_('hello world'))
然后根据user选择的语言,创建translation对象,然后调用install方法install_()函数
到Python’s builtins namespace。如:

import gettext
en_trans = gettext.install('messages', locale='i18n_path', languages=['default_language'])
zh_trans = gettext.install('messages', locale'i18n_path', languages=['zh_CH'])
print(_('hello world'))
zh_trans.install()
print(_('hello world'))

而对于web服务中前端页面的国际化支持也非常简单,和python source文档中一样
在需要国际化的字符串前面添加_()即可。然后在render函数中,把当前translation对象
传入模板即可。如Tornado render_string的实现:

def render_string(self, template_name, **kwargs):
        # If no template_path is specified, use the path of the calling file
        ... ...
        args = dict(
            handler=self,
            request=self.request,
            current_user=self.current_user,
            locale=self.locale,
            _=self.locale.translate,             
            static_url=self.static_url,
            xsrf_form_html=self.xsrf_form_html,
            reverse_url=self.application.reverse_url
        )
        args.update(self.ui)
        args.update(kwargs)
        return t.generate(**args)

好了,上面搭建好i18n所需要的环境,下面就是准备对语言字符资源了。

python 工具: pygettext msgfmt

其他工具: msgmerge
1. 创建po文档

在当前目录下创建locale文件夹,下面分别建en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/目录。
在locale下面创建名为 demo.html的文件内容如下:
<html>
	<head>
		<title>${_('title')}</title>
	</head>
	<body>
	<a href=''>${_('body')}</a>
</body>
</html>

然后打开命令行窗口,输入 python pygettext.py -a -v -d messages -o messages.po \*.py \*.html
完成后,在当前目录生成 messages.po 文件。
打开message.po 会看到其中的格式内容:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\\n"
"POT-Creation-Date: %(time)s\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: LANGUAGE <LL@li.org>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=CHARSET\\n"
"Content-Transfer-Encoding: ENCODING\\n"
"Generated-By: pygettext.py %(version)s\\n"

#: demo.html:3
msgid "title"
msgstr ""

#: demo.html:6
msgid "body"
msgstr ""


说明:  #: demo.html:3
msgid "title"      #待转换的字符串
msgstr ""          #转换后的字符bytes,如果为空,则返回原字符

关键信息:"Content-Type: text/plain; charset=CHARSET\n
这里的CHARSET 指定了 msgstr的codeset。一般推荐charset设定为utf-8.
关于msgstr保存的信息需要说明:实际上它是一个bytes,是翻译后的字符串
调用encode结果。
而当调用_()函数时,实际上会调用translation设置的默认charset来decode(具体请参考gettext module)。
即我们在message.po设置的charset。

2. 翻译字符资源
将生成的messages.po的分别copy至 en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/目录下。
分别切换至en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/ 目录,
编辑messages.po,修改添加翻译后的字符(注:source.encode(charset))

3. 生成mo文件
分别切换目录至en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/,
在命令行输入: python msgfmt.py messages.po 生成mo文件。

最终生成的locale tree的目录类似linux系统的/usr/share/locale,
 locale/{lang}/LC_MESSAGES/{domain}.mo

测试:

>>> import gettext
>>> en_trans = gettext.translation('messages', 'e:/python/locale', languages=['en_US'])
>>> zh_trans = gettext.translation('messages', 'e:/python/locale', languages=['zh_CN'])
>>> en_trans.gettext('title'), en_trans.gettext('body')
('title', 'body')
>>> zh_trans.gettext('title'), zh_trans.gettext('body')
('HTML Head 头', 'HTML Body 测试')
>>> en_trans.install()
>>> _('title'), _('body'), _('hello')
('title', 'body', 'hello')
>>> zh_trans.install()
>>> _('title'), _('body'), _('hello')
('HTML Head 头', 'HTML Body 测试', 'hello')

上例使用的python解析器是python3.2.2 2.*版本有些method参数稍有不同,请注意!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值