Jinja2:在循环内更改变量的值

Sha*_*bus 62 python jinja2

我想在循环中更改在循环外声明的变量的值.但总是在改变,它将初始值保持在循环之外.

{% set foo = False %}

{% for item in items %}
  {% set foo = True %}
  {% if foo %} Ok(1)! {% endif %}
{% endfor %}

{% if foo %} Ok(2)! {% endif %}
Run Code Online (Sandbox Code Playgroud)

这呈现:

Ok(1)!
Run Code Online (Sandbox Code Playgroud)

所以到目前为止唯一(坏)解决方案是:

{% set foo = [] %}

{% for item in items %}
  {% if foo.append(True) %} {% endif %}
  {% if foo %} Ok(1)! {% endif %}
{% endfor %}

{% if foo %} Ok(2)! {% endif %}
Run Code Online (Sandbox Code Playgroud)

这呈现:

Ok(1)!
Ok(2)!
Run Code Online (Sandbox Code Playgroud)

但是,它非常难看!还有其他更优雅的解决方案吗?

Pas*_*hka 60

尝试也基于字典的方法.它似乎不那么难看.

{% set vars = {'foo': False} %}

{% for item in items %}
  {% if vars.update({'foo': True}) %} {% endif %}
  {% if vars.foo %} Ok(1)! {% endif %}
{% endfor %}

{% if vars.foo %} Ok(2)! {% endif %}
Run Code Online (Sandbox Code Playgroud)

这也呈现:

Ok(1)!
Ok(2)!
Run Code Online (Sandbox Code Playgroud)

  • 仍然很难看,但它确实有效.我很惊讶没有Pythonic的方式与jinja2这样做. (4认同)
  • 绝对更干净一点,尤其是当您需要多个变量时 (2认同)
  • @ kramer65:解决方案似乎正在起作用:https://github.com/pallets/jinja/pull/684; https://github.com/pallets/jinja/pull/676 (2认同)

Ome*_*mer 29

如文档中所述:

请注意,循环中的赋值将在迭代结束时清除,并且不能超过循环范围.

但从版本2.10开始,您可以使用名称空间:

    {% set ns = namespace(foo=false) %}      
    {% for item in items %}
      {% set ns.foo = True %}
      {% if ns.foo %} Ok(1)! {% endif %}
    {% endfor %}

    {% if ns.foo %} Ok(2)! {% endif %}
Run Code Online (Sandbox Code Playgroud)

  • 小写的false是jinja约定的一部分:“`特殊常量true,false和没有一个确实是小写的。因为这在过去引起了混淆,(True曾经扩展为一个未定义的变量,被认为是false),所以这三个都可以现在也以标题大小写(True,False和None)编写。但是,为了保持一致(所有Jinja标识符均为小写),应使用小写版本。 (3认同)
  • 您说“ namespace(foo = false)”是Falseja中的小写字母f是jinja2口语,还是说False(如python要求的布尔值)? (2认同)