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

Disable GNU gettext function "_()" temporarily in Python

提问人:buhtz 提问时间:8/16/2023 最后编辑:buhtz 更新时间:10/12/2023 访问量:53

问:

我确实使用 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 实用程序确实需要第二行来确定哪些字符串是可翻译的并且应该进入 / 文件。正因为如此,我不能这样做,因为gettext utils不知道是什么。popotoriginal

original = 'Hello'
translated = _(original)

也许我尝试了错误的方式。我可以交替地提出我的问题:如何在不复制 python 源代码中的字符串的情况下,以原始源(未翻译)形式显示一个字符串并逐个站点翻译?

python gettext

评论

1赞 DeepSpace 8/16/2023
你没有无限递归吗?
0赞 buhtz 8/16/2023
优秀的眼睛!修改了问题。原来的问题仍然存在。
1赞 STerliakov 8/16/2023
如果在函数中条件性地定义,则将变成一个函数范围的变量,该变量不再与全局变量有任何共同之处。___
0赞 buhtz 8/16/2023
我不知何故明白这一点。但是我怎样才能屏蔽/禁用?_()
0赞 buhtz 8/17/2023
是否有可能以某种方式操纵 buildints 命名空间?

答:

0赞 Guido Flohr 10/12/2023 #1

这应该有效:

def N_(msgid):
    return msgid


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

您只需要配置消息提取器以将参数也提取到函数。N_

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

如果代码没有意义,这里有一个更深入的解释: 所有 gettext 翻译函数(、、、、...)都有双重用途:在运行时,它们为相关消息提供翻译。在“消息提取时”,它们将字符串标记为可翻译。该函数通常只标记字符串,但实际上不会在运行时检索翻译。gettext()ngettext()pgettext()_()N_()

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

注意:我不是 Python 专家,因此不知道您是否必须自己定义无操作函数,或者它是否默认可用。你会自己发现的。N_()