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參數稍有不一樣,請注意!
相關文章
相關標籤/搜索