DjangoやPythonにおける*argsと**kwargsとは何か

結論から言うと、*argsはキーワード未指定の引数のリスト、**kwargsはキーワードが指定された引数の辞書を手に入れるためのものである。
*argsはキーワード未指定の引数のリスト
まずは、下記コードを参考にしたい。
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
def main(name,*args):
print(name)
print(args)
if __name__ == "__main__":
try:
main("Tom","Mike","Bob")
except KeyboardInterrupt:
print("\nprogram was ended.\n")
sys.exit()
main()関数に3つの文字列の引数を与えている。"Tom","Mike","Bob"の文字列引数が与えられているが、関数が受け取れるのはnameと*argsの2つのみ。"Bob"が受け取れないからエラーになると思われるが、実際に上記のコードを実行してみると、こうなる。

print(args)を実行した時、リスト型の('Mike', 'Bob')が表示されるのがわかる。これがキーワード未指定の引数のリストを返す、*argsである。
**kwargsはキーワードが指定された引数の辞書
では、関数を呼び出す時に、引数にキーワードを指定するとどうなるだろうか?
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
def main(name,*args):
print(name)
print(args)
if __name__ == "__main__":
try:
main(name="Tom",name1="Mike",name2="Bob")
except KeyboardInterrupt:
print("\nprogram was ended.\n")
sys.exit()
main()関数でnameが定義されているので"Tom"は読み込めるが、name1とname2は読み込めないのでエラーになってしまう。ここでキーワード引数の辞書を返す**kwargsの出番である。下記コードを見てもらいたい。
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
def main(name,*args,**kwargs):
print(name)
print(args)
print(kwargs)
if __name__ == "__main__":
try:
main(name="Tom",name1="Mike",name2="Bob")
except KeyboardInterrupt:
print("\nprogram was ended.\n")
sys.exit()
上記コードを実行すると、下記のようになる。

つまり、キーワード引数(name="Tom"のような形)を受け取って辞書型にするのが**kwargsで、キーワードなしの引数("Tom"のような形)を受け取ってリスト型にするのが*argsである。
先のコードではキーワード引数のみなので、キーワード指定なしの引数をmain()内に指定してあげると、print(args)で表示される。

結論
様式美として、大多数のコードでは*argsと**kwargsと名付けているが、別に*listsとか*args_listでも問題はない。
重要なのはアスタリスク(*)を変数名の前に1つでキーワード未指定の引数のリストを、2つでキーワードが指定された引数の辞書を返す仕組みになっている。
では、なぜDjangoのviews.pyのクラスで*argsと**kwargsがそれぞれメソッドの引数に指定されているかと言うと、URLconf(urls.py)から引数を指定してviews.pyのメソッドを呼び出すとき、エラーが発生しないようにするためにある。*argsと**kwargsが無い場合、与える引数を過不足無く、かつ指定したキーワードに即して与えなければならない状況に至るからである。