<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jinja &#8211; 李辉 / Grey Li</title>
	<atom:link href="https://greyli.com/tag/jinja/feed/" rel="self" type="application/rss+xml" />
	<link>https://greyli.com</link>
	<description>一个编程和写作爱好者的在线记事本</description>
	<lastBuildDate>Thu, 06 Nov 2025 11:36:11 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.26</generator>

<image>
	<url>https://greyli.com/wp-content/uploads/2025/03/avatar-500-compressed-144x144.jpg</url>
	<title>Jinja &#8211; 李辉 / Grey Li</title>
	<link>https://greyli.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>如何向Jinja宏传递额外参数（*args和**kwargs）？</title>
		<link>https://greyli.com/use-kwargs-args-in-jinja-macro/</link>
		<comments>https://greyli.com/use-kwargs-args-in-jinja-macro/#respond</comments>
		<pubDate>Mon, 22 Oct 2018 04:34:31 +0000</pubDate>
		<dc:creator><![CDATA[李辉]]></dc:creator>
				<category><![CDATA[计算机与编程]]></category>
		<category><![CDATA[Flask]]></category>
		<category><![CDATA[Flask Web开发实战]]></category>
		<category><![CDATA[Jinja]]></category>

		<guid isPermaLink="false">http://greyli.com/?p=1957</guid>
		<description><![CDATA[这段时间有多个读者问关于Jinja宏定义时的参数接受问题。这一点在《Flask Web开发实战》里没有介绍，这 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>这段时间有多个读者问关于Jinja宏定义时的参数接受问题。这一点在<a href="http://helloflask.com/book">《Flask Web开发实战》</a>里没有介绍，这篇文章作为一个补充。</p>
<h2>一个不符合直觉的设定</h2>
<p>在某个晴朗的早晨，你打开电脑，想在你的项目Jinja模板里编写一个宏来简化操作。按照直觉，你可能会像定义Python函数那样来定义宏，传入**kwargs来让它接收任意数量的关键字参数，比如：</p>
<pre name="c58a" id="c58a" class="graf graf--pre graf-after--p">{% macro say_hello(**kwargs) %}
     ...
{% endmacro %}</pre>
<p>或是传入*args让它接收任意数量的位置参数：</p>
<pre name="c58a" id="c58a" class="graf graf--pre graf-after--p">{% macro say_hello(*args) %}
     ...
{% endmacro %}</pre>
<p>遗憾的是，上面的调用会分别获得下面的错误信息：</p>
<div class="detail">
<pre class="errormsg">jinja2.exceptions.TemplateSyntaxError: expected token 'name', got '**'</pre>
<div class="detail">
<pre class="errormsg">jinja2.exceptions.TemplateSyntaxError: expected token 'name', got '*'</pre>
</div>
</div>
<h2>在Jinja宏里接收额外的关键字参数和位置参数</h2>
<p>在Jinja中，宏默认会自动接收额外的关键字参数和位置参数，并在宏内部提供<strong>kwargs</strong>和<strong>varargs</strong>特殊变量来获取它们。具体来说，在定义宏的时候，不需要进行任何声明。在宏的内部，你可以直接使用kwargs字典来获取额外的关键字参数；同样的，你可以使用varargs元组来获取额外传入的位置参数。</p>
<p>下面是使用kwargs的示例：</p>
<pre class="">{% macro say_hello() %}
    &lt;p&gt;Hello, {{ kwargs['name'] }}!&lt;/p&gt;
{% endmacro %}

{# 调用示例 #}
{{ say_hello(name='Grey')}}</pre>
<p class="">你可以把这个字典传递给其他函数，比如url_for()：</p>
<pre class="">{% macro nav_link(endpoint, text) %}
    &lt;a href="{{ url_for(endpoint, **kwargs) }}"&gt;{{ text }}&lt;/a&gt;
{% endmacro %} 

{# 调用示例 #}
{{ nav_link('index', 'Home', foo='value1', bar='value2')}}</pre>
<p>下面是使用varargs的示例：</p>
<pre class="">{% macro say_hello() %}
    &lt;p&gt;Hello, {{ varargs[0] }}!&lt;/p&gt;
{% endmacro %}

{# 调用示例 #}
{{ say_hello('Grey')}}</pre>
<p>提示 在宏内部，如果kwargs字典里没有对应的键，那么会返回空字符串，而不是抛出KeyError异常；如果向varargs元组索引一个超出范围的下标值，也会返回空值，而不会抛出IndexError异常。</p>
<h2>隐藏的陷阱</h2>
<p>虽然宏自动处理额外传入的关键字参数和位置参数，但是这里有一个隐藏的小陷阱。如果你在调用一个宏的时候传入了额外的关键字参数和位置参数，但是宏的内部并没有使用它们，这时就会出错。比如下面使用kwargs的示例：</p>
<pre class="">{% macro say_hello() %}
    &lt;p&gt;Hello!&lt;/p&gt;
{% endmacro %} 

{# 调用示例 #} 
{{ say_hello(name='Grey')}}</pre>
<p>调用宏的时候传入了name参数，但是宏内部并没有使用它，这时Jinja会抛出下面的异常：</p>
<div class="detail">
<pre class="errormsg">TypeError: macro 'say_hello' takes no keyword argument 'name'</pre>
</div>
<p>类似的是位置参数，你会获得下面的异常：</p>
<pre class="">TypeError: macro 'say_hello' takes not more than 1 argument(s)</pre>
<p class="">所以，如果你想让某个宏接收额外的关键字参数或位置参数，你就分别需要在这个宏内部至少调用一次（access）kwargs字典或是varargs元组。一般情况下，你并不需要担心这个问题。</p>
<p>本文隶属于<a class="internal" href="https://zhuanlan.zhihu.com/p/42734345" data-za-detail-view-id="1043">《Flask Web开发实战》番外文章</a>系列。</p>
]]></content:encoded>
			<wfw:commentRss>https://greyli.com/use-kwargs-args-in-jinja-macro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
