渲染Jinja2模板后,是否可以获取设置值?
After rendering a Jinja2 template, can I get the set values?
我想渲染一个Jinja2模板,渲染后读取它设置的值:
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
这会打印:
Hello Ned 42!
{'name': 'Ned'}
在 template.render
之后我可以做些什么来获得 number
的价值?另外,我需要在事先不知道名字 number
的情况下进行。我想发现模板中设置的任何值。
根据提供的上下文:
import jinja2
import re
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
rendered = template.render(vars).strip()
print(vars)
print(rendered)
changed_var_value = re.findall(r'Hello[\s\S]*\s{1}(.*)!', rendered)
print(f'var after the greeting: {changed_var_value}')
输出:
{'name': 'Ned'}
Hello Ned 42!
var after the greeting: ['42']
我想,这有点骇人听闻,但您似乎可以使用 jinja2.runtime
中的 Context
做一些事情,例如
$ cat show_vars.py
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
from jinja2 import Environment
from jinja2.runtime import Context
env = Environment()
ctx = Context(env, vars, '', template.blocks)
list(template.root_render_func(ctx))
print(ctx.vars)
print(ctx.get_all())
$ python show_vars.py
Hello Ned 42!
{'name': 'Ned'}
{'number': 42}
{'name': 'Ned', 'number': 42}
正如@nedbat指出的那样,也可以用
达到同样的效果
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
list(template.root_render_func(ctx))
print("get_all:", ctx.get_all())
print("exported_vars:", ctx.exported_vars)
print("vars:", ctx.vars)
这是一种不使用记录在案但不使用它们的函数的方法:
import jinja2
template = jinja2.Template("""
{% set number = 52 %}
{% set choice = "apple" %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
template.render(ctx)
mod = template.module
template_vars = {n:getattr(mod, n) for n in dir(mod) if not n.startswith("_")}
print(template_vars)
这会打印:
{'also': 'foo', 'choice': 'apple', 'number': 52}
我想渲染一个Jinja2模板,渲染后读取它设置的值:
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
这会打印:
Hello Ned 42!
{'name': 'Ned'}
在 template.render
之后我可以做些什么来获得 number
的价值?另外,我需要在事先不知道名字 number
的情况下进行。我想发现模板中设置的任何值。
根据提供的上下文:
import jinja2
import re
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
rendered = template.render(vars).strip()
print(vars)
print(rendered)
changed_var_value = re.findall(r'Hello[\s\S]*\s{1}(.*)!', rendered)
print(f'var after the greeting: {changed_var_value}')
输出:
{'name': 'Ned'}
Hello Ned 42!
var after the greeting: ['42']
我想,这有点骇人听闻,但您似乎可以使用 jinja2.runtime
中的 Context
做一些事情,例如
$ cat show_vars.py
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
from jinja2 import Environment
from jinja2.runtime import Context
env = Environment()
ctx = Context(env, vars, '', template.blocks)
list(template.root_render_func(ctx))
print(ctx.vars)
print(ctx.get_all())
$ python show_vars.py
Hello Ned 42!
{'name': 'Ned'}
{'number': 42}
{'name': 'Ned', 'number': 42}
正如@nedbat指出的那样,也可以用
达到同样的效果import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
list(template.root_render_func(ctx))
print("get_all:", ctx.get_all())
print("exported_vars:", ctx.exported_vars)
print("vars:", ctx.vars)
这是一种不使用记录在案但不使用它们的函数的方法:
import jinja2
template = jinja2.Template("""
{% set number = 52 %}
{% set choice = "apple" %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
template.render(ctx)
mod = template.module
template_vars = {n:getattr(mod, n) for n in dir(mod) if not n.startswith("_")}
print(template_vars)
这会打印:
{'also': 'foo', 'choice': 'apple', 'number': 52}