使用Pyramid和Python 3进行国际化

3 投票
3 回答
1163 浏览
提问于 2025-04-17 15:59

现在Pyramid在使用Python 3时的国际化支持情况怎么样呢?

目前看起来,Pyramid用来处理国际化的两个包,lingua和babel,似乎都不支持Python 3。

有一个链接是 https://bitbucket.org/felixschwarz/babel-py3k,但是没有官方发布的版本。

至于lingua,我只找到了一些叫做lingua3k的影子信息,但到处的链接都坏了,也没有官方发布的版本。

我该如何在Python 3中使用Pyramid的国际化功能呢?

3 个回答

1

要按照自己的方式翻译一个Python应用程序,通常有两个主要步骤:

  • 提取消息目录
  • 翻译字符串

第一个步骤是由Babel和lingua来处理,第二个步骤则是用gettext(或者它的其他封装工具,比如translationstring)。

简短回答:下载Poedit来处理目录工作,使用常规的Pyramid库进行翻译。

详细回答

如果Babel和lingua对你不适用,你可以自己创建消息目录。然后,使用现有的.pot文件,你可以为每种语言创建.po文件。如果你使用Poedit,它可以自动将你的.po文件编译成.mo文件。这些文件可以仅用Python的标准库gettext来处理,而不需要其他依赖。

具体步骤是:使用Poedit创建一个消息目录(文件->新建目录)。仔细设置所有选项。Poedit甚至可以提取字符串,可能你在这里不需要手动操作,只需查看源路径源关键字目录属性中。

然后你翻译所有提取的(或手动添加的)字符串。Pyramid会期待以下的目录结构:

myproject/
    locale/
        en/
            LC_MESSAGES/
                myproject.po
                myproject.mo
        myproject.pot

这个pot文件就是你的目录。en文件夹是用来翻译成英语的。对于其他语言,你可以在这里放入相应的语言代码:de代表德语,es代表西班牙语,等等。你可以先创建一个空的.po文件,然后让Poedit从.pot文件中更新。

翻译完成后,使用Pyramid的文档来了解如何处理这些文件。如果你能用其他方式提取消息,就不需要Babel。

顺便提一下:你在翻译过程中使用的所有工具都是围绕Python的gettext库构建的,所以如果遇到任何问题,你甚至可以直接使用这个库。只要你有一个有效的目录,这种方法在任何情况下都能工作。

5

Py3 状态更新 2013年6月28日

这是对2013年3月发布的两个答案的更新,适合任何偶然看到这个内容的人。

关于 Python 3 的 Babel 项目,目前还没有官方发布的版本。维护者在这里有一个未解决的问题:http://babel.edgewall.org/ticket/209

不过,有一群人接过了这个项目,开始在 BitBucket 上建立一个非官方的 Babel3 代码库:https://bitbucket.org/babel3_developers/babel3

Pyramid 也使用了 lingua。目前,如果你尝试使用 easy_install 或 pip 安装 lingua,会失败。原因是 xlwt 还没有被官方移植。

如果你想安装 lingua,就需要手动修补 xlwt。

安装非官方的 Babel3

现在,Python 3 的 Babel 还没有官方发布的版本。pypi 上也没有相关内容(也就是说,使用 easy_install babel/babel3 或 pip install babel/babel3 是无法正常工作的)。不过,你可以使用非官方的版本。

  1. 要获取非官方版本,首先你需要安装 mercurial(一个源代码管理工具)。你需要这个工具来从 BitBucket 下载源代码。Windows 用户可以在这里获取:https://www.mercurial-scm.org/。Linux/Unix 用户可以使用你们的发行版工具获取二进制文件或从源代码编译。
  2. 在命令提示符下,导航到你想临时存储 Babel3 源代码安装文件的目录,然后运行:hg clone https://bitbucket.org/babel3_developers/babel3(Windows 用户可能需要输入 hg.exe 的完整路径,或者确保将 hg.exe 所在的目录添加到系统路径中)
  3. 这会在你的本地计算机上创建一个包含 setup.py 文件的目录。进入这个新目录并执行文件:python setup.py install

安装 Lingua

Pyramid 的国际化(i18n)依赖于另一个名为 lingua 的 Python 模块。它与另一个依赖模块 xlwt 有问题。这个问题也在这里得到了非官方的修补:https://github.com/tonyroberts/xlwt

  1. 在这里获取修补版本的 xlwt 源代码:https://github.com/tonyroberts/xlwt(点击右下角的“下载 zip”)
  2. 将内容解压到临时位置
  3. 在结果目录内打开命令提示符
  4. 运行:python setup.py install
  5. 现在通过:pip install lingua -or- easy_install lingua 安装 lingua
3

我找不到关于在Python 3中使用Pyramid框架的i18n(国际化)辅助包(比如babel和lingua)当前或未来状态的任何信息。

为了应对这个问题,我做了四件事:

  1. 创建了一个使用Python 2.7的第二个虚拟环境。
  2. 添加了一个特定的国际化设置文件,叫做setup_i18n.py。
  3. 写了一个简单的脚本,叫做translate.py,这个脚本会被setup.py调用来进行翻译。
  4. 在setup.py中添加了一个入口点,指向translate脚本。

具体细节:

  1. 我在我的项目中创建了一个非常简单的Python 2.7虚拟环境,叫做env_python_2.7,并把它放在项目的根目录下。

  2. 然后在setup.py所在的目录里,我创建了另一个设置文件setup_i18n.py。这个文件只包含国际化支持所需的内容。我的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),
          ]},
      )

  1. 接着,我创建了一个叫做translate.py的脚本,并把它放在与初始化数据库的脚本initializedb.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()

  1. 最后,我修改了setup.py中的入口点,让它指向translate脚本。我的入口点看起来是这样的:


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
""",

现在我可以通过运行 'python3 setup.py my_project_translate' 来进行应用的国际化处理。

撰写回答