jinja2宏中的*args和**kwargs

69
Jinja2宏如何处理额外的args和kwargs?文档并不是很清楚。
例如,下面的代码显然是错误的:
{% macro example_1(one, two, **kwargs) %}
    do macro stuff
{% endmacro %}

这导致了
jinja2.exceptions.TemplateSyntaxError

TemplateSyntaxError: expected token 'name', got '**'

文档中写道:

kwargs

类似于varargs,但是用于关键字参数。所有未使用的关键字参数都存储在这个特殊变量中。

不幸的是,任何额外的关键字参数组合都会导致错误,

{% macro example_2(one, two) %}
    do macro stuff
{% endmacro %}

{{ example_2(one, two, test='test') }}

TypeError: macro 'example_2' takes no keyword keyword argument 'test'

我没有例子,也没有在浏览Jinja2源代码。目前文档对我来说不太清晰。欢迎任何想法。

听起来好像不支持任意关键字参数。也许可以使用类似 {% macro example_2(one, two, test=None) %} 的方式? - Chris Morgan
2个回答

84

关键在于任何需要接受 kwargs 的宏都必须至少被调用一次。也就是说,在宏的正文中必须调用{{ kwargs }},而不在宏参数列表中声明它。对于 {{ varargs }} 也是如此。

否则将无法正常工作。

{% macro example_2(one, two) %}
    * {{one}} - {{two}}
{% endmacro %}
{{example_2(1, 2, test="Hello")}}

这将会

{% macro example_2(one, two) %}
    * {{one}} - {{two}}
    * {{kwargs}}
{% endmacro %}
{{example_2(1, 2, test="Hello")}}

79
哇,那是一个非常不好的设计选择。 - BrenBarn
3
我同意你的观点,@BrenBarn - Jinja 有很多很棒的东西,但是那些神奇的伪全局变量并不属于这一类。 - Sean Vieira
3
我不会说这非常棒,但至少我们可以将它作为评论放置在渲染时剥离出来。 {# {{kwargs}} #} - Taylor D. Edmiston
1
这种注释的方法对我不起作用。可能是与版本有关。 - Jakob Simon-Gaarde
5
你的意思是我应该写{% if False %}{{ kwargs }}{% endif %}还是Taylor写的那个版本?哦... - hyperknot
显示剩余4条评论

0

仅仅是为了补充Sean Viera的答案kwargs对象将会是一个字典,所以如果你想使用它,你可以通过访问items()方法来迭代它,就像在普通的Python中一样

{% macro iterate_kwargs() %}
    {% for key, value in kwargs.items() %}
    The key, {{ key }}, has a value of {{ value }}
    {%- endfor -%}
{% endmacro %}

{{ iterate_kwargs(id=123, colour="blue", size="S") }}

这将输出以下内容:
    The key, id, has a value of 123
    The key, colour, has a value of blue
    The key, size, has a value of S

这篇文章是使用dbt编写和测试的,因此可能不适用于所有使用Jinja的工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接