Python项目的多语言翻译babel
最近项目要做多语言适配,查了一下babel是个不错的选择。
babel的github主页上有flask-babel, django-babel, babel
本文以flask-babel为例,记录一下使用过程的注意事项
1. 安装
pip install Flask-Babel
2. 使用
from flask import Flask
from flask_babel import Babeldef get_locale(): # Flask-Babel# otherwise try to guess the language from the user accept# header the browser transmits. We support de/fr/en in this# example. The best match wins.return request.accept_languages.best_match(['zh', 'en'])app = Flask(__name__)
Babel(app, locale_selector=get_locale, default_locale='zh')# 它会根据浏览器的header: accept-language zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 来判断用户使用的语言,自动选择对应的翻译
在需要翻译的地方,加上对应的函数:(建议全使用英文,它会把这段英文作为ID,去匹配翻译, 见后文例子)
from flask_babel import gettext,ngettext,lazy_gettext,lazy_ngettext# 常规翻译
gettext('Parameter error')# 对方语言有单复数区分时(比如中文1颗苹果,2颗苹果,没有单复数区别;但英语就有单复数区分:1 Apple,2 Apples)
ngettext('%(num)s Apple', u'%(num)s Apples', number_of_apples)
# ngettext需要把目标语言的单复数翻译都写上(前面单数翻译,后面复数翻译),翻译时 它会自动根据变量的值来选择单数翻译 or 复数翻译# 翻译内容需要结合上下文情景时(需要把变量插到要翻译的句中),比如这里要标明是那个参数错误:
lazy_gettext('Invalid Parameter: %(value)s', value=var)
# Lazy strings will not be evaluated until they are actually used.
3. 提取翻译内容
根目录下增加babel.cfg文件:
[python: **.py]
表示从所有.py文件中提取翻译内容
# Usage: pybabel extract [options] <input-paths>
# 在项目的根目录下执行
pybabel extract -F babel.cfg -k "lazy_gettext lazy_ngettext" -o messages.pot --no-wrap .
# 它默认只提取gettext,ngettext,如果你使用了lazy_gettext,需要加 -k参数指定
# 如果翻译内容太长,超过Python规范的单行长度,会被自动换行,--no-wrap 就是让它别给我自动换行
# 更多参数的意思,自行pybabel extract --help 查看
上面命令执行后,项目根目录下 会多出一个 messages.pot 文件
msgid "Parameter error"
msgstr ""#, python-format
msgid "Invalid Parameter: %(value)s"
msgstr ""
4. 初始化、更新翻译内容
如果你是第一次使用,执行命令:
pybabel init -i messages.pot -d target_dir/translations -l zh --no-wrap
# -l 指定各种语言 zh/de/fr 等等
# 这段命令执行过后,项目根目录/target_dir 下会生成一些目录、文件:
├─translations
│ └─zh
│ └─LC_MESSAGES
│ messages.po# 此时messages.po的内容和messages.pot一样
如果不是第一次使用,就不执行上面的命令,执行更新命令:
pybabel update -i messages.pot -d target_dir/translations --no-wrap
这个命令会把第3步提取出来的内容(messages.pot)合并到messages.po
5. 编写翻译内容
打开messages.po文件,人工写入每一条翻译:
msgid "Parameter error"
msgstr "参数错误"#, python-format
msgid "Invalid Parameter: %(value)s"
msgstr "参数错误:%(value)s"
此时有个注意事项:
通常更新后,.po 文件中可能出现 fuzzy标识,这是因为你修改了一些翻译内容,它在更新合并的时候,无法确定msgid 和msgstr的对应关系,需要你人工检查修改,否则,有fuzzy标识的翻译 通常都是不对的,它不会将其编译到最终的翻译文件中,除非编译时明确指定--use-fuzzy
(这个坑困扰了我很久,我想着 明明写了翻译,却翻译不出来,后来发现是fuzzy的原因)
6. 编译最终使用的翻译文件
# 执行命令:
pybabel compile -d target_dir/translations# 此时翻译目录会多出一个 messages.mo 文件,这个就是最终使用到的翻译文件
├─translations
│ └─zh
│ └─LC_MESSAGES
│ messages.mo
│ messages.po
好了,我只写了基本使用的主要过程,通常情况够用了,更多还需要你们自行探索