Python多模块gettext翻译不一致 全局变量/函数实现最佳实践
问题根因
问题本质是Python模块变量的导入绑定逻辑导致:import B的执行时机早于A模块中翻译实例的初始化,B模块在导入阶段就已经将_固定绑定为默认无翻译的gettext.gettext函数,后续A模块对自身模块级_的修改完全不会影响B模块内已经完成的赋值。
业界最佳实践方案
方案1:统一封装翻译工具模块(最推荐)
单独维护一个全局翻译管理模块,所有业务模块统一从该模块导入_,保证全项目共用同一个翻译实例,后续扩展多语言切换、动态修改配置都更方便。
- 新增
i18n.py翻译管理模块:
import gettext # 全局翻译实例 _trans = gettext def init_locale(lang_code: str): global _trans if lang_code == "de": _trans = gettext.translation("base", localedir="locales", languages=["de"]) else: _trans = gettext def _(text: str) -> str: return _trans.gettext(text)
- 修改
A.py,优先完成翻译初始化再执行业务逻辑:
from B import print_text2 from i18n import init_locale, _ language = "de" # 翻译初始化必须早于所有翻译调用 init_locale(language) def print_text1(): print(_("Power consumption")) print_text1() print_text2()
- 修改
B.py,统一从翻译模块导入_:
from i18n import _ def print_text2(): print(_("Warm Water"))
方案2:注册翻译函数到内置命名空间(适合小型项目)
如果项目规模小不想新增模块,可以把翻译函数注册到Python全局内置命名空间,所有模块无需单独导入即可直接使用_,注意必须保证翻译初始化代码的执行时机早于所有业务代码。
- 修改
A.py:
import gettext import builtins from B import print_text2 language = "de" if language == "de": de = gettext.translation("base", localedir="locales", languages=["de"]) de.install() builtins._ = de.gettext else: builtins._ = gettext.gettext def print_text1(): print(_("Power consumption")) print_text1() print_text2()
- 修改
B.py,删除原有_变量的赋值:
def print_text2(): print(_("Warm Water"))
补充注意事项
- 不要用
is判断字符串相等,字符串驻留是CPython实现细节,is判断会有不可预期的错误,统一用==做字符串判等 - 所有翻译字符串要保证属于同一个翻译域,避免
xgettext提取待翻译字符串时出现遗漏
内容的提问来源于stack exchange,提问作者Erysol
相关产品推荐
相关产品推荐

