【问题标题】:ugettext and ugettext_lazy functions not recognized by makemessages in Python DjangoPython Django 中的 makemessages 无法识别 ugettext 和 ugettext_lazy 函数
【发布时间】:2013-05-06 17:25:24
【问题描述】:

我正在使用 Django 1.5.1,并且在翻译时遇到了一些“奇怪的行为”。我在同一个 Python 文件中使用 ugettextugettext_lazy。如果我将导入组织为:

from django.utils.translation import ugettext as trans
from django.utils.translation import ugettext_lazy as _

from django.utils.translation import ugettext as trans, ugettext_lazy as _

运行makemessages 命令时会跳过标记为trans("string") 的字符串。

但是,如果我不重命名 ugettext,它适用于两个版本:

from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _

from django.utils.translation import ugettext, ugettext_lazy as _

现在trans("string") 运行良好。

那么,有人知道为什么这个导入重命名会导致重命名的函数不被调用吗?这是一个实际的 Python“限制”,我在重命名多个函数时不知道同一个模块?


更新

经过一些测试,我意识到即使使用以下代码在应用程序中创建一个空的 python 模块也不起作用:

from django.utils.translation import ugettext_lazy as translate

a = translate("string")

但是,如果使用 _ 作为别名,它可以工作:

from django.utils.translation import ugettext_lazy as _

a = _("string")

我的结论是:你只能在 Django 中为ugettextugettext_lazy(或任何其他相关的翻译函数)使用_ 别名,否则它不会被makemessages 命令识别。技术解释可以在 Robert Lujo 的回答中找到。

谢谢!

【问题讨论】:

  • 您可以根据需要“重命名”任意数量的符号(函数或其他),Python 名称只是别名,并且两种导入形式(一个衬里或两个衬里)是等效的,所以问题是别处。 FWIW 我强烈怀疑您在导入后将名称“trans”重新绑定到其他地方...
  • 嗨!我没有在模块中覆盖trans(我用 Eclipse 进行了搜索)。可能因为'_'重命名吗?
  • _ 是一个有效的 Python 名称,没有神奇的力量。 wrt/重命名,from x import y as zfrom x import y; z = y; del y 完全相同,所以这里再次没有任何神奇的事情发生。 wrt/您的断言“您没有覆盖trans”,简单的文本搜索可能还不够。一个非常常见的(反)模式是星形导入覆盖,即from x import y; from z import *,其中z 也导出y 符号。另外,如果您不熟悉 Python,Python 的函数 存在于孤立的命名空间中,它们是普通变量。
  • 我不知道是否会与名为 trans 或 translate 的任何 Django 变量发生名称冲突。我的想法不多了。我不在 Python 中使用狂野的导入来避免问题。
  • @brunodesthuilliers 我刚刚在进一步测试后更新了我的问题。

标签: python django internationalization


【解决方案1】:

另一种解决不生成 .po 文件的方法是开发服务器。

在我的开发服务器运行期间,我执行了命令 ma​​kemessage。命令输出正确,但我的 .po 文件已更新:

(venv_crypto_bot) macbook-pro:django_project dauzon$ python manage.py makemessages -a 
processing locale fr
processing locale en
processing locale ru

停止开发服务器并重新运行命令解决了我的问题。

【讨论】:

    【解决方案2】:

    可以通过覆盖makemessages 命令来处理意外的 ugettext 别名,例如:

    from django.core.management.commands import makemessages
    
    class Command(makemessages.Command):
        """
        Extends the makemessages command to look for additional aliases.
        """
        xgettext_options = makemessages.Command.xgettext_options + ['--keyword=_lazy']
    

    https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#customizing-the-makemessages-command

    【讨论】:

      【解决方案3】:

      Django 命令实用程序 makemessages 在内部调用xgettext 程序,如下所示:

      cmd = (
          'xgettext -d %s -L Python %s %s --keyword=gettext_noop '
          '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
          '--keyword=ugettext_noop --keyword=ugettext_lazy '
          '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
          '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
          '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
          '--add-comments=Translators -o - "%s"' %
          (domain, wrap, location, work_file))
      

      (来源可以找到here)。因此,xgettext 实用程序预定义了一些关键字(请查看 --keyword 参考):

      • 对于 python - gettext、ugettext、dgettext、ngettext、ungettext、dngettext、_

      还有一些是由 django 实用程序添加的:

      • gettext_lazy , ngettext_lazy , ugettext_noop , ugettext_lazy , ungettext_lazy , pgettext , npgettext , pgettext_lazy , npgettext_lazy

      关键字 trans 不在这些关键字集中,因此您不应使用它来标记要翻译的文本。

      【讨论】:

      • 感谢您的回答,经过进一步测试,我刚刚更新了我的问题。
      • 这正是问题所在!我正在使用未包含在关键字中的别名重命名 ugettextugettext_lazy 函数,因此它被跳过了。这不是进口的问题。所以,总而言之,只说允许的唯一别名是_。感谢您的回答! :)
      【解决方案4】:

      这些关于multi-language support for Django project 的注释可以让您找出问题所在。重命名很可能不是失败的根本原因。

      这些注释中的一些警告:

      • 您网站的每个模板都必须使用 {% load %} 加载 i18n 标记库

      • 您需要在运行 makemessages 之前手动创建语言环境目录 - 您通常会这样做,否则您会收到错误消息

      • 在使用语言文件之前,必须将它们编译为 .mo 文件 - 你也这样做了

      编辑

      在我链接到我的帖子的页面中,他们在模板中使用了这种语法:

      {% trans "Hello" %}
      

      你已经尝试过了吗?

      【讨论】:

      • 问题与此无关,因为使用 ugettext_lazy as _ 可以完美地工作,并且使用不带别名的 ugettext。
      • 我刚刚接受了@RobertLujo 的回答,因为他完美地回答了我的问题。无论如何谢谢:)
      猜你喜欢
      • 2011-05-29
      • 2014-04-26
      • 1970-01-01
      • 2018-03-26
      • 2022-06-14
      • 2018-08-08
      • 1970-01-01
      • 2020-11-01
      • 1970-01-01
      相关资源
      最近更新 更多