Babel如何同时使用msgstr与msgid且不产生重复静态字符串
Babel 国际化:如何在不重复编写字符串的前提下同时获取原始msgid和翻译后msgstr
问题描述
尝试通过变量复用字符串减少代码重复时,遇到Babel字符串提取失效的问题:
msg = 'User request is completed' logging.info(msg) reply(_(msg)) # Babel无法提取变量形式传入的`msg`作为待翻译条目
已知Babel的静态提取逻辑无法识别传入的变量参数,需要找到可行方案,既在代码中同时保留原始msgid和翻译后msgstr,又不影响Babel的正常提取流程。
当前如果要满足「日志记录msgid、接口返回msgstr」的需求,只能重复编写完全相同的静态字符串:
from flask_babel import _ # 期望实现仅需维护一处字符串,无需同步修改两处 logging.info('User request is completed') # 记录原始msgid到日志 reply(_('User request is completed')) # 返回翻译后的msgstr作为接口响应
核心诉求
- 日志固定记录原始
msgid:使用固定语言(英文)记录日志更便于后续检索排查,如果日志内容是克林贡语这类小语种翻译结果,会大幅提升问题排查难度。例如日志固定记录User request is completed,接口返回对应克林贡语翻译qaStaHvIS qemlI'即可满足要求 - 接口响应返回对应语言的
msgstr - 不破坏Babel的原生字符串提取流程
- 支持带占位符的字符串格式化场景,无需重复编写格式化逻辑
- 消除重复的静态字符串代码,降低后续维护成本
目前技术栈使用flask_babel,该问题属于Babel生态的通用使用问题,暂未找到官方提供的标准解决方案。
已尝试的实现思路
最初考虑封装一个辅助函数,同时返回翻译结果和原始msgid:
# msg: 翻译后的字符串,例如'qaStaHvIS qemlI' # msgid: 原始字符串标识,例如'User request is completed' msg, msgid = gettext_and_id('User request is completed') # Babel本身未提供该内置方法 logging.info(msgid) reply(msg)
查阅flask-babel源码确认官方未提供类似功能的函数,虽然可以快速实现基础版辅助函数,但方案存在明显缺陷:
- 基础版实现逻辑简单,但场景覆盖能力不足:
from flask_babel import gettext def gettext_and_id(msgid): return gettext(msgid), msgid
- 处理
{file} is not found这类带占位符的字符串时,需要分别对翻译结果和原始msgid执行两次格式化操作,代码冗余:
filename = 'neverland' # ... 文件不存在的业务处理逻辑 msg, msgid = gettext_and_id('{file} is not found') msg = msg.format(file=filename) msgid = msgid.format(file=filename)
期望方案
需要更优雅的实现方式,同时满足所有核心诉求,无需重复编写字符串或格式化逻辑,且完全兼容Babel的原生字符串提取流程。
内容的提问来源于stack exchange,提问作者Louis Go
相关产品推荐
相关产品推荐

