Pyramid 使用 Babel 和 Lingua 实现国际化(I18N)支持,但目前对于 Python 3 的兼容性仍存在一些问题。
- Babel 目前还没有正式发布支持 Python 3 的版本,虽然有开发者创建了一个非官方的 Babel3 仓库,但尚未集成到 Pyramid 中。
- Lingua 在安装时会失败,因为其依赖的 xlwt 模块尚未移植到 Python 3。
- 解决方案:
方法一:使用非官方 Babel3 和 Lingua 补丁
步骤:
- 使用 Mercurial(版本控制工具)克隆 Babel3 源代码:
hg clone https://bitbucket.org/babel3_developers/babel3
- 进入 Babel3 目录并安装:
cd babel3
python setup.py install
- 修补 Lingua 并安装:
- 下载 xlwt 补丁:https://github.com/tonyroberts/xlwt
- 解压并进入 xlwt 目录
- 运行
python setup.py install
- 安装 Lingua:
pip install lingua
方法二:在独立的 Python 2.7 环境中处理 I18N
这个方案需要你创建一个独立的 Python 2.7 环境,只在其中安装和运行 I18N 相关的任务,其它项目代码仍然使用 Python 3。
步骤:
- 创建Python 2.7 的虚拟环境。
- 在虚拟环境中安装 Babel 和 Lingua。
- 创建一个 I18N 设置文件
setup_i18n.py
,用于指定 I18N 相关的依赖项。 - 创建一个翻译脚本
translate.py
,用于提取、更新和编译消息目录。 - 在项目根目录的
setup.py
中添加入口点,指向translate.py
脚本。 - 现在,您可以通过调用
python3 setup.py my_project_translate
来进行翻译。
方法三:使用 Poedit 和 Python 标准库 gettext
步骤:
- 使用 Poedit 创建消息目录。
- 翻译字符串。
- 创建 .po 文件并编译成 .mo 文件。
- 在项目代码中使用 Python 标准库 gettext 处理翻译后的字符串。
代码例子:
在 setup_i18n.py
中:
from setuptools import setup, find_packages
requires = [
'Babel',
'lingua',
]
setup(name='my_project',
packages=find_packages(),
install_requires=requires,
message_extractors={'.': [
('**.py', 'lingua_python', None),
('**.pt', 'lingua_xml', None),
]},
)
在 translate.py
中:
import argparse
import subprocess
import sys
from pyramid.paster import (
get_appsettings,
setup_logging,
)
description = """\
A script to facilitate the translation of strings in the app.
"""
parser = argparse.ArgumentParser(description=description)
parser.add_argument('ini_file', help='Ini file to setup environment for this script')
parser.add_argument('-a', '--add', metavar='locale',
help='Add locale name of new language for translation (eg: en, de)')
def main(argv=sys.argv):
args = parser.parse_args()
setup_logging(args.ini_file)
settings = get_appsettings(args.ini_file)
# Python 2.7 is needed for translation strings at this time, because the
# available translation string tools are not compatible with Python 3
# at this time
python27 = settings['my_project.python27_dir'] + '/bin/python'
setup_file = settings['my_project.i18n_setup_file']
if args.add:
subprocess.call([python27, setup_file, 'init_catalog', '-l', args.add])
subprocess.call([python27, setup_file, 'extract_messages'])
subprocess.call([python27, setup_file, 'update_catalog'])
subprocess.call([python27, setup_file, 'compile_catalog'])
if __name__ == '__main__':
main()
在 setup.py
中:
entry_points="""\
[paste.app_factory]
main = my_project:main
[console_scripts]
my_project_db = my_project.script.initializedb:main
my_project_translate = my_project.script.translate:main
""",