如何从Python模块访问Jinja模板中set定义的变量?
获取Jinja模板中{% set %}定义的变量值
Jinja的{% set %}变量仅在模板渲染的上下文环境中生效,直接加载模板文件不会执行这些赋值语句,可通过以下两种方式提取变量:
方法一:渲染模板并捕获上下文
通过渲染模板(即使模板无输出内容),将{% set %}定义的变量写入传入的上下文字典:
from jinja2 import Environment, FileSystemLoader # 初始化环境,指定模板所在目录 env = Environment(loader=FileSystemLoader('./')) # 加载目标模板 template = env.get_template('result.j2') # 创建空上下文字典,用于接收模板变量 context = {} # 渲染模板,变量会自动写入context template.render(context) # 提取目标变量 file_name = context.get('file_name') print(file_name) # 输出: foo
说明:这种方式简单直接,但如果模板中存在其他未定义的依赖变量,需要先在context中补全,否则渲染会抛出变量未定义的异常。
方法二:解析模板AST提取变量
如果不想渲染模板(比如模板依赖大量未定义变量),可以直接解析模板的抽象语法树(AST)提取赋值语句:
from jinja2 import Environment, FileSystemLoader from jinja2.parser import Parser import jinja2.nodes as nodes env = Environment(loader=FileSystemLoader('./')) # 获取模板源码 template_source = env.loader.get_source(env, 'result.j2')[0] # 解析源码生成AST parser = Parser(env, template_source) ast = parser.parse() # 遍历AST节点,提取Set类型的赋值 extracted_vars = {} for node in ast.find_all('Set'): # 处理单个变量赋值的场景 if isinstance(node.target, nodes.Name): var_name = node.target.name # 仅处理常量值的赋值(可根据需求扩展复杂值处理) if isinstance(node.node, nodes.Const): extracted_vars[var_name] = node.node.value # 获取目标变量 file_name = extracted_vars.get('file_name') print(file_name) # 输出: foo
说明:这种方式无需渲染模板,但需要对Jinja的AST节点结构有基础了解,上述代码仅处理简单的常量赋值场景,若模板中存在循环、条件内的{% set %}或复杂表达式赋值,需要扩展节点处理逻辑。
内容的提问来源于stack exchange,提问作者karim gamil
相关产品推荐
相关产品推荐

