模板视图 - kwargs和** kwargs

时间:2016-09-29 19:38:25

标签: python django

我正在阅读有关模板视图的教程和一些让我感到困惑的代码。作者使用了此代码示例

from django.utils.timezone import now

class AboutUsView(TemplateView):
    template_name = 'about_us.html'

def get_context_data(self, **kwargs):
    context = super(AboutUsView, self).get_context_data(**kwargs)
    if now().weekday() < 5 and 8 < now().hour < 18:
        context['open'] = True
    else:
        context['open'] = False
    return context

语法上让我困惑的是这句话

 context = super(AboutUsView, self).get_context_data(**kwargs)

如果我们已经收到**kwargs那么为什么我们用**(双启动)将它传递给超级函数。我认为我们应该将其作为

传递
 context = super(AboutUsView, self).get_context_data(kwargs)

这是接收此电话的contextMixin。

class ContextMixin(object):
    """
    A default context mixin that passes the keyword arguments received by
    get_context_data as the template context.
    """

    def get_context_data(self, **kwargs):
        if 'view' not in kwargs:
            kwargs['view'] = self
        return kwargs

据我所知,使用**kwargs几乎意味着kwargs目前是一个字典,需要转换为命名值。如果这是正确的话,当kwargs的参数实际上是** kwargs时,kwargs怎么能成为字典。我希望我的问题有道理。如果您希望我改写一下,请告诉我。

2 个答案:

答案 0 :(得分:3)

在函数声明中,**kwargs将获取所有未指定的关键字参数并将其转换为字典。

>>> test_dict = {'a':1, 'b':2}
>>> def test(**kwargs):
...     print (kwargs)
...
>>> test(**test_dict)
{'b': 2, 'a': 1}

请注意,字典对象在传递给函数(**)时以及函数接收时必须使用test(**test_dict)进行转换。不可能做到以下几点:

>>> test(test_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes 0 positional arguments but 1 was given

因此,在您的示例中,第一个**kwargs将关键字参数解压缩到字典中,然后第二个将它们打包回来以发送给父级。

签名中具有**kwargs的函数可以接收解压缩的字典或未指定的关键字参数。这是第二种情况的一个例子:

>>> def test(arg1, **kwargs):
...     print (kwargs)
...
>>> test('first', a=1, b=2)
{'b': 2, 'a': 1}

答案 1 :(得分:2)

在你的函数定义中,它接受多个参数,并将它们解析为dict。 def get_context_data(self, **kwargs):

现在,kwargs是一个字典对象。因此,如果将其传递给.get_context_data(kwargs),则必须只需要一个传入参数,并将其视为字典。

因此,当您第二次执行**kwargs时,您正在将字典炸回到将扩展到该函数调用的关键字参数中。