You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jinja2的PackageLoader渲染模板时脚本重复执行两次的问题

使用Jinja2的PackageLoader渲染模板时脚本重复执行两次的问题

这个问题我之前也踩过坑!核心原因其实是Python模块导入的机制加上你没给脚本加执行防护导致的,咱们一步步理清楚:

为什么会重复执行?

你用PackageLoader('basic')的时候,Jinja2会让Python去导入名为basic的模块——也就是你的basic.py脚本。而如果你的脚本里没有任何执行防护代码,当它被当作模块导入时,整个脚本的代码会从头到尾跑一遍,相当于你直接运行脚本的同时,又被自己导入执行了一次,所以才会出现模板渲染两次的情况。

你用空的other_script.py能正常工作,是因为导入这个模块时,里面没有任何执行逻辑,自然不会触发额外的模板渲染。

两种靠谱的解决方法

方法1:给脚本加上if __name__ == '__main__':防护

这是Python脚本的标准实践,能精准区分“直接运行脚本”和“作为模块被导入”两种场景。把你的执行逻辑放到这个判断里,这样当basic.py被PackageLoader导入时,只会加载函数/变量定义,不会执行渲染和打印的逻辑。

修改后的basic.py代码:

#!/usr/bin/env python3
from jinja2 import Environment, PackageLoader, select_autoescape

def render_my_template():
    env = Environment(
        loader=PackageLoader('basic'),
        autoescape=select_autoescape()
    )
    return env.get_template('basic_template.md').render({'version': 'version123', 'date': 'some-date'})

# 只有直接运行这个脚本时,才会执行下面的代码
if __name__ == '__main__':
    print(render_my_template())

方法2:改用FileSystemLoader替代PackageLoader

如果你的场景里不需要用Python包的方式来加载模板,直接用FileSystemLoader指定模板目录的绝对路径会更直观,也完全避开模块导入的问题,在CI环境里这种方式有时候反而更可控,因为你可以明确指定模板的位置,不用担心包结构的影响。

修改后的代码示例:

#!/usr/bin/env python3
from jinja2 import Environment, FileSystemLoader, select_autoescape
import os

# 获取当前脚本所在的绝对目录(避免CI环境中相对路径失效的问题)
current_script_dir = os.path.dirname(os.path.abspath(__file__))
# 拼接templates目录的路径
templates_path = os.path.join(current_script_dir, 'templates')

env = Environment(
    loader=FileSystemLoader(templates_path),
    autoescape=select_autoescape()
)

print(env.get_template('basic_template.md').render({'version': 'version123', 'date': 'some-date'}))

这两种方法都能完美解决你遇到的重复执行问题,你可以根据自己的项目结构和CI环境选择更合适的一种~

备注:内容来源于stack exchange,提问作者jeremywat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:47:59