在Django的源代码中,有**kwargs
和**initkwargs
。
django/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__))
它们在使用方面有何不同?
答案 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)。
所以即使这两者之间没有太大的区别,并且它可能只是一个很好的实践,我不会说这是无关紧要的。