在 Python 中暂时禁用 GNU gettext 函数“_()”

问题描述 投票:0回答:1

我确实使用 GNU gettext 及其基于类的 API,因此将

_()
安装在 Python
builtins
命名空间中。我想在全局范围内暂时禁用翻译。

我试图通过用局部函数定义对其进行着色来以某种方式“屏蔽”

_()
。但我得到了这些错误:

No problem.
Traceback (most recent call last):
  File "/home/user/ownCloud/_transfer/./z.py", line 27, in <module>
    .format(foobar(True), foobar(False)))
  File "/home/user/ownCloud/_transfer/./z.py", line 19, in foobar
    return _('Hello')
UnboundLocalError: local variable '_' referenced before assignment

这是MWE

#!/usr/bin/env python3
import gettext

translation = gettext.translation(
    domain='iso_639',
    languages=['de'],
    localedir='/usr/share/locale'
)
translation.install()  # installs _() in "buildins" namespace
# Keep in mind: The object "translation" is not avialble in the original
# productive code because it is instanciated elsewhere.

def foobar(translate):
    if not translate:
        # I try to mask the global _() builtins-function
        def _(txt):
            return txt

    return _('Hello')

if __name__ == '__main__':

    # To ilustrate that _() is part of "builtins" namespace
    print(_('No problem.'))

    print('The translated string "{}" is originally "{}".'
          .format(foobar(True), foobar(False)))

在我原来的高效代码中,我尝试以两种方式显示一个大的多行字符串:未翻译和已翻译。但我不想在这样的代码中重复该字符串。

original = 'Hello'
translated = _('Hello')

据我所知,GNU gettext 实用程序确实需要第二行来确定哪些字符串是可翻译的,并且应该放入

po
/
pot
文件中。因此,我不能这样做,因为 gettext utils 不知道
original
是什么。

original = 'Hello'
translated = _(original)

也许我尝试的方式不对。或者,我可以这样表述我的问题:如何以原始源(未翻译)形式显示一个字符串,并逐个站点地翻译该字符串,而不在 python 源代码中复制该字符串?

python gettext
1个回答
0
投票

这应该有效:

def N_(msgid):
    return msgid


original = N_(msgid)
translated = _(msgid)

您只需配置消息提取器即可提取函数的参数

N_

如果您使用 GNU gettext 附带的

xgettext
提取消息,则必须使用
--keyword=N_
明确添加该关键字(这有点烦人,因为它是大多数语言的默认关键字,但不是 Python)。如果您使用 PyBabel,它默认关键字,请参阅https://babel.pocoo.org/en/latest/cmdline.html#extract

如果代码没有意义,这里有一个更深入的解释:所有 gettext 翻译函数(

gettext()
ngettext()
pgettext()
_()
,...)都有双重目的:运行时,它们提供相关消息的翻译。在“消息提取时”,它们将字符串标记为可翻译。函数
N_()
通常只是标记字符串,但实际上并不在运行时检索翻译。

但是为什么提取器不会被

_(msgid)
触发呢?因为提取器只提取字符串文字,但从不提取变量。在运行时,
_()
/
gettext()
和朋友的参数是(静态)消息目录的查找键,它显然必须是常量。

注意:我不是 Python 专家,因此不知道您是否必须自己定义无操作函数

N_()
还是默认情况下可用。你自己就会发现的。

© www.soinside.com 2019 - 2024. All rights reserved.