Pythonの *args と **kwargs の基本と、Djangoでの使われ方
はじめに
Pythonで関数やクラスを定義していると、以下のような記述を見かけます。
def some_func(*args, **kwargs):
...
*args と **kwargsは「引数をたくさん受け取れるもの」と漠然と理解していても、
その意味を理解していないと形式的に書くだけになってしまうことがあります。
本記事では、*args と **kwargs について、
基本からDjangoなど実務でどう活用されているかについて解説します。
1. *args と **kwargs とは
まずは、*argsと**kwargsの役割を押さえておきましょう。
*args:複数の「位置引数(名前なしの引数)」をまとめて受け取る
def greet(*args):
for name in args:
print(f"こんにちは、{name}さん")
greet("山田", "佐藤", "高橋")
# ☝️ このように「名前なし」で渡された引数を、まとめて受け取るのが *args
# こんにちは、山田さん
# こんにちは、佐藤さん
# こんにちは、高橋さん
-
argsはタプルになります(例:("山田", "佐藤", "高橋"))。
関数定義で*argsと書くことで、渡された複数の引数をタプルとしてまとめて受け取れるようになります。
**kwargs:複数の「キーワード引数(名前つきの引数)」をまとめて受け取る
def introduce(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
introduce(name="山田", age=30)
# ☝️ このように「名前つき」で渡された引数が kwargs に入る
# name: 山田
# age: 30
-
kwargsは辞書になります。(例:{"name": "山田", "age": 30})
関数定義で**kwargsと書くことで、渡された複数の名前付き引数を辞書としてまとめて受け取れるようになります。
❗️両方使うときの順番に注意
def func(a, b, *args, **kwargs):
...
順番は以下の通りで、固定になります。
通常の引数 → *args → **kwargs
2. Djangoで見かける *args, **kwargs
*args, **kwargs は、Djangoの中で頻繁に使われています。
特に クラスベースビュー(CBV) や URLパラメータの受け取りでよく使われます。
🔸 クラスベースビュー(CBV)とは
Djangoで画面表示などの処理を「関数」ではなく「クラス」で書くスタイルのことです。
たとえばView,TemplateView,FormViewなどが該当します。
最初は難しく感じるかもしれませんが、Djangoの公式ドキュメントやチュートリアルでも少しずつ登場します。
この記事では細かく掘り下げませんが、
「クラスでビューを定義する書き方がある」くらいの認識で大丈夫です。
使用例①:クラスベースビュー(CBV)の dispatch
class MyView(View):
def dispatch(self, request, *args, **kwargs):
...
-
*argsは未使用でも、親クラスから引き継ぐときに必要 -
**kwargsには、URLパターンから渡された引数が入っている
例:
# urls.py
path("user/<int:pk>/", MyView.as_view(), name="user-detail")
# views.py
def get(self, request, *args, **kwargs):
user_id = kwargs.get("pk")
このとき、kwargs には {"pk": 42} のような形で URL パラメータが渡されます。
使用例②:super() に渡す
class MyFormView(FormView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
super() を使うことで、親クラス(ここでは FormView)の __init__() を呼び出すことができます。
🔸 補足:
super()は継承している親クラスを指します
この例ではMyFormViewがFormViewを継承しているので、super()はFormViewを指しています。
*argsや**kwargsをそのまま渡すことで、
親クラス側で必要な引数が追加された場合でも対応できる、という柔軟さがあります。
将来的に親クラスの引数が増減しても自分のクラスを修正しなくて済むというメリットがあります。
3. *args と **kwargsを使用する理由
書き方も大事ですが、なぜ使うかが重要です。
- 将来的に引数が増えるかもしれないときに備える
- 受け取る内容がバラバラな処理を一括で吸収することができる
- Django や Django REST framework の内部処理に引き継ぐために必要なことがある
おわりに
*args と **kwargs は、最初はわかりにくいかもしれませんが、
「引数をまとめて受け取るための仕組み」です。
Django や Django REST frameworkの世界では頻繁に出てくるので、
意味を知っているだけでコードの見通しが良くなります。
本記事が理解の一助となれば幸いです。
Discussion
可変長引普通の引数の混在ですが、実際には*argsと**kwargsの間に普通の引数を定義できます。(つまり、普通の引数、*args、普通の引数、**kwargsは可能です)
ただし、その間の引数は(直前の*argsが受けとるために)キーワード専用引数と振る舞います。
コメントありがとうございます!
本記事では基本の使い方に絞って紹介していましたが、確かにそのような記述も可能ですね。
補足ありがとうございます!