Python中临时禁用GNU gettext的_()函数及原译字符串同显方案
解决GNU gettext临时禁用翻译时的UnboundLocalError问题
错误原因
你遇到的UnboundLocalError是Python作用域规则导致的:当函数内部任何位置对变量_进行赋值(包括用def定义同名函数),Python会将整个函数内的_视为局部变量。当translate=True时,if not translate分支不执行,局部的_从未被定义,此时调用_('Hello')就会触发未绑定局部变量的错误。
可行解决方案
方案1:局部显式绑定gettext函数
在函数开头根据条件直接定义_的实现,确保_在所有分支都被正确赋值:
#!/usr/bin/env python3 import gettext import builtins # 直接引用builtins模块,避免依赖__builtins__的实现细节 translation = gettext.translation( domain='iso_639', languages=['de'], localedir='/usr/share/locale' ) translation.install() def foobar(translate): # 条件选择翻译逻辑:禁用时返回原文本,否则使用系统内置的翻译函数 _ = lambda txt: txt if not translate else builtins._ return _('Hello') if __name__ == '__main__': print(_('No problem.')) print('The translated string "{}" is originally "{}".' .format(foobar(True), foobar(False)))
方案2:用上下文管理器临时切换翻译状态
适合需要在一段代码块中临时禁用翻译的场景,不影响函数外的翻译功能:
#!/usr/bin/env python3 import gettext import builtins translation = gettext.translation( domain='iso_639', languages=['de'], localedir='/usr/share/locale' ) translation.install() class DisableTranslation: def __enter__(self): # 保存原翻译函数 self.original_gettext = builtins._ # 替换为直接返回原文本的函数 builtins._ = lambda txt: txt return self def __exit__(self, exc_type, exc_val, exc_tb): # 退出上下文时恢复原翻译函数 builtins._ = self.original_gettext def foobar(translate): if translate: return _('Hello') else: with DisableTranslation(): return _('Hello') if __name__ == '__main__': print(_('No problem.')) print('The translated string "{}" is originally "{}".' .format(foobar(True), foobar(False)))
方案3:一次性获取原文本和翻译文本
针对你需要同时展示原字符串和翻译版本的场景,封装函数直接返回两者,避免重复编写字符串:
#!/usr/bin/env python3 import gettext import builtins translation = gettext.translation( domain='iso_639', languages=['de'], localedir='/usr/share/locale' ) translation.install() def get_translated_and_original(txt): # 先获取翻译后的文本 translated = _(txt) # 临时替换翻译函数获取原文本 original_gettext = builtins._ builtins._ = lambda x: x original = _(txt) # 恢复原翻译函数 builtins._ = original_gettext return translated, original if __name__ == '__main__': print(_('No problem.')) translated, original = get_translated_and_original('Hello') print(f'The translated string "{translated}" is originally "{original}".')
所有方案都保留了_('字符串')的格式,完全兼容GNU gettext的po/pot文件提取工具,不会破坏翻译流程。
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

