3秒でわかる
引数を省略したときに使われる値を関数側に書いておく仕組み。呼び出し側の記述を減らしつつ、既存の呼び出しを壊さずに引数を増やせます。
もう少し詳しく
どういうものか
関数を定義するときに def send(text, retry=3) のように書いておくと、呼び出し側が retry を渡さなかった場合に 3 が使われます。この = 3 の部分がデフォルト引数です。ほとんどの呼び出しで同じ値になる引数を、毎回書かずに済ませるための書き方です。
Python、JavaScript、Kotlin、Swift など多くの言語が同じ記法を持ちます。Java にはこの仕組みが無く、代わりに引数の数が違う同名メソッドを複数用意するオーバーロードで対応します。
なぜ必要か
既存のコードを壊さずに機能を足せることが最大の利点です。すでに50か所から呼ばれている関数に新しい引数を追加するとき、デフォルト値を付けておけば既存の50か所は1文字も直さずに動き続けます。新しい振る舞いが欲しい場所だけが値を渡します。
具体例
def greet(name, greeting="こんにちは", mark="。"):
return f"{greeting}、{name}さん{mark}"
print(greet("佐藤")) # こんにちは、佐藤さん。
print(greet("佐藤", "おはよう")) # おはよう、佐藤さん。
print(greet("佐藤", mark="!")) # こんにちは、佐藤さん!JavaScript でも同じ書き方ができます。
function fetchPage(url, { retry = 3, timeout = 5000 } = {}) {
return { url, retry, timeout };
}
fetchPage("/api/users"); // retry 3, timeout 5000
fetchPage("/api/users", { retry: 1 }); // retry 1, timeout 5000def add_item(item, basket=[]): # 危険
basket.append(item)
return basket
print(add_item("りんご")) # ['りんご']
print(add_item("みかん")) # ['りんご', 'みかん'] 空のはずが残っている回避策は、デフォルト値を None にしておき、関数の中で「None なら空のリストを作る」と書き直すことです。JavaScript のデフォルト値は呼び出しのたびに評価されるため、この問題は起きません。言語ごとに評価のタイミングが違う点が要注意です。
もう1つ、デフォルト値を持つ引数は持たない引数より後ろに並べる必要があります。順番を逆にすると定義の時点で構文エラーになります。
覚え方
「省略されたときの保険」と考えます。保険の中身が全員で共有される箱 (リスト) だと事故になる、というのが Python の罠です。