`** kwargs`和`** initkwargs`的功能不同

时间:2017-11-10 15:29:32

标签: django

在Django的源代码中,有**kwargs**initkwargsdjango/base.py at master · django/django

class View:

    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in kwargs.items():
            setattr(self, key, value)

    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))

它们在使用方面有何不同?

2 个答案:

答案 0 :(得分:1)

虽然kwargs是常规名称,但它被称为initkwargs的主要原因是为了避免名称冲突:

@classonlymethod
def as_view(cls, **initkwargs):
    """Main entry point for a request-response process."""
    ...

    def view(request, *args, **kwargs):  # defines kwargs
        self = cls(**initkwargs)         # uses initkwargs
        ...
        return self.dispatch(request, *args, **kwargs)
    ...
    return view

请注意,内部view函数采用**kwargs参数。如果classmethod使用相同的名称,则内部**kwargs将遮蔽外部**kwargs,并且在实例化kwargs时函数将无法访问外部cls

使用名称initkwargs可以避免此问题。

答案 1 :(得分:0)

正如评论所说,两者背后的机制没有区别。重要的部分是HasFieldNames:=。话虽如此,我想补充两者的区别似乎来自**用于类实例化的事实。实际上,它始终与**initkwargs一起使用,cls通常代表用于类方法的第一个参数PEP 8)。

所以即使这两者之间没有太大的区别,并且它可能只是一个很好的实践,我不会说这是无关紧要的。