如何修改/合并Jinja2词典?

Bri*_*unt 16 merge dictionary jinja2

我有一个Jinja2字典,我想要一个修改它的表达式 - 通过改变它的内容,或者与另一个字典合并.

>>> import jinja2
>>> e = jinja2.Environment()
Run Code Online (Sandbox Code Playgroud)

修改字典:失败.

>>> e.from_string("{{ x[4]=5 }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "jinja2/environment.py", line 743, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "jinja2/environment.py", line 469, in compile
    self.handle_exception(exc_info, source_hint=source)
  File "<unknown>", line 1, in template
jinja2.exceptions.TemplateSyntaxError: expected token
                                            'end of print statement', got '='
Run Code Online (Sandbox Code Playgroud)

两阶段更新:打印多余的"无".

>>> e.from_string("{{ x.update({4:5}) }} {{ x }}").render({'x':{1:2,2:3}})
u'None {1: 2, 2: 3, 4: 5}'
>>> e.from_string("{{ dict(x.items()+ {3:4}.items()) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "jinja2/environment.py", line 868, in render
    return self.environment.handle_exception(exc_info, True)
  File "<template>", line 1, in top-level template code
TypeError: <lambda>() takes exactly 0 arguments (1 given)
Run Code Online (Sandbox Code Playgroud)

使用dict(x,**y):失败.

>>> e.from_string("{{ dict((3,4), **x) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "jinja2/environment.py", line 868, in render
    return self.environment.handle_exception(exc_info, True)
  File "<template>", line 1, in top-level template code
TypeError: call() keywords must be strings
Run Code Online (Sandbox Code Playgroud)

那么如何x通过更改属性或与另一个字典合并来修改Jinja2中的字典呢?

这个问题类似于:如何将两个Python词典合并为一个表达式? - 就Jinja2和Python类似而言.

小智 28

我找到了另一个没有任何扩展的解

{% set _dummy = x.update({4:5}) %}
Run Code Online (Sandbox Code Playgroud)

它使x更新.不要使用_dummy.

  • 这应该是我接受的答案^^ (3认同)

Gar*_*ett 24

听起来像Jinja2"do"语句扩展可能有所帮助.启用此扩展程序将允许您重写:

{{ x.update({4:5}) }} {{ x }} 
Run Code Online (Sandbox Code Playgroud)

{% do x.update({4:5}) %} {{ x }}
Run Code Online (Sandbox Code Playgroud)

例:

>>> import jinja2
>>> e = jinja2.Environment(extensions=["jinja2.ext.do",])
>>> e.from_string("{% do x.update({4:5}) %} {{ x }}").render({'x':{1:2,2:3}})
u' {1: 2, 2: 3, 4: 5}'
>>> 
Run Code Online (Sandbox Code Playgroud)

  • 另一个习惯用法是{{x.update({4:5})| default(x,true)}}`。 (2认同)

Bri*_*unt 6

我添加了一个过滤器来合并字典,即:

>>> def add_to_dict(x,y): return dict(x, **y)
>>> e.filters['add_to_dict'] = add_to_dict
>>> e.from_string("{{ x|add_to_dict({4:5}) }}").render({'x':{1:2,2:3}})
u'{1: 2, 2: 3, 4: 5}'
Run Code Online (Sandbox Code Playgroud)