这个错误是因为在较新版本的 Jinja2(3.0+)中,jinja2.ext.autoescape 和 jinja2.ext.with_ 这两个扩展已经被移除(它们的功能现在是默认开启的)。而你的 babel.cfg 配置文件中可能仍然按照旧教程写了:

[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_

执行 pybabel extract 时,Babel 会尝试导入这些扩展,从而引发 AttributeError


🔧 解决方案

方案一(推荐):移除 extensions 行

对于大多数 Flask 项目,Jinja2 模板中只需要识别 _() 函数即可,而 Babel 默认就能识别模板中的 _(),不需要额外扩展。最简单的做法是直接删除 extensions 这一行:

# babel.cfg
[python: **.py]
[jinja2: **/templates/**.html]

如果模板中使用了自定义过滤器或高级语法,Babel 仍然可以正常工作,因为 _() 是全局函数。


方案二:仅保留 i18n 扩展

如果你的模板中使用了 ngettext 或复杂的翻译逻辑,有时需要显式指定 jinja2.ext.i18n 扩展(但 Flask-Babel 已经自动注册了,通常不必)。不过,如果一定要写,只写这一个即可:

[jinja2: **/templates/**.html]
extensions=jinja2.ext.i18n

不要 再包含 autoescape 和 with_


📦 检查依赖版本

建议确认你使用的 Flask-Babel 和 Jinja2 版本是否兼容:

pip list | grep -E "Flask-Babel|Jinja2"
  • Flask-Babel 2.0.0+ 支持 Jinja2 3.0+

  • Jinja2 3.1+ 已移除 autoescape 和 with_ 扩展

如果版本过旧,可以考虑升级:

pip install --upgrade Flask-Babel Jinja2

🧪 验证修复

修改 babel.cfg 后,重新执行提取命令:

pybabel extract -F babel.cfg -o messages.pot .

如果不再报错,说明问题已解决。继续后续的 initupdate 和 compile 步骤即可。


💡 补充说明

  • 为什么旧教程会那样写? 因为 Jinja2 2.x 版本中,autoescape 和 with_ 是可选扩展,需要显式启用,但现在它们已是内置行为。

  • Flask-Babel 已自动处理:在 Flask 应用中,Babel 初始化时会自动将 _ 函数注入模板上下文,所以 Babel 提取器无需额外扩展也能捕获模板中的翻译标记。

按照以上任意一种方案修改后,你的 Flask 多语言配置就能正常工作了