python gettext : specify locale in _()

标签 python multithreading python-3.x internationalization gettext

当请求翻译 gettext 中的字符串时,我正在寻找一种即时设置语言的方法。我会解释原因:

我有一个多线程机器人,它在多台服务器上通过文本回复用户,因此需要用不同的语言回复。 documentation gettext 声明,要在运行时更改语言环境,您应该执行以下操作:

import gettext # first, import gettext

lang1 = gettext.translation('myapplication', languages=['en']) # Load every translations
lang2 = gettext.translation('myapplication', languages=['fr'])
lang3 = gettext.translation('myapplication', languages=['de'])

# start by using language1
lang1.install()

# ... time goes by, user selects language 2
lang2.install()

# ... more time goes by, user selects language 3
lang3.install()

但是,这不适用于我的情况,因为机器人是多线程的:

假设以下 2 个片段同时运行:

import time
import gettext 
lang1 = gettext.translation('myapplication', languages=['fr'])
lang1.install()
message(_("Loading a dummy task")) # This should be in french, and it will
time.sleep(10)
message(_("Finished loading")) # This should be in french too, but it wont :'(

import time
import gettext 
lang = gettext.translation('myapplication', languages=['en'])
time.sleep(3) # Not requested on the same time
lang.install()
message(_("Loading a dummy task")) # This should be in english, and it will
time.sleep(10)
message(_("Finished loading")) # This should be in english too, and it will

您可以看到消息有时会翻译成错误的语言环境。 但是,如果我可以做类似 _("string", lang="FR") 的事情,问题就会消失!

我是不是漏掉了什么,或者我使用了错误的模块来完成任务... 我正在使用 python3

最佳答案

虽然上述解决方案似乎有效,但它们不能很好地与别名为 gettext() 的常规 _() 函数一起使用.但我想保留该功能,因为它用于从源中提取翻译字符串(参见 docs 或例如 this blog)。

因为我的模块运行在多进程多线程环境下,using the application’s built-in namespacea module’s global namespace不会工作,因为如果多个线程安装不同的翻译,_() 将是一个共享资源并受制于竞争条件。

因此,首先我编写了一个返回翻译闭包的简短辅助函数:

import gettext

def get_translator(lang: str = "en"):
    trans = gettext.translation("foo", localedir="/path/to/locale", languages=(lang,))
    return trans.gettext

然后,在使用翻译字符串的函数中,我将该翻译闭包分配给 _,从而使其成为我的本地范围内所需的函数 _()在不污染全局共享 namespace 的情况下运行:

def some_function(...):
    _ = get_translator()  # Pass whatever language is needed.

    log.info(_("A translated log message!"))

(将 get_translator() 函数包装到 memoizing cache 中以避免多次创建相同闭包的额外加分项。)

关于 python gettext : specify locale in _(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37998300/

相关文章:

python - 如何测试范围的等价性

python - 如何将 Pandas 数据框中的一列复制到另一个数据框中,同时匹配两者中公共(public)列的值?

python - Neomodel 类定义

python - 为什么我的简单 python 列表在 for 循环中重置为 None ?

java - 带线程的对话框消息

python - 如何在命令行中判断文件是否为字符串以及是否存在

python - python中的分区字符串并获取冒号后最后一段的值

c++ - 从另一个线程调用 CFRunLoopStop 是否安全?

java - 将 String 转换为泛型类型 <T extends Comparable<T>>

python-3.x - 在Python中填充两个不同长度的数据集