【第10回Python基礎講座】関数の応用(1):引数のデフォルト値

本ページはプロモーションが含まれています
【第10回Python基礎講座】関数の応用(1):引数のデフォルト値
国内のAI狂い

やっほー!国内のAI狂いだよ!✨

第10回へようこそ!今回は、関数をより賢くするための「デフォルト引数」のお話。
これを使うと、「普段はおまかせ設定、こだわりの時だけ指定」みたいな便利な関数が作れるよ。
でもね、ここには「リストをデフォルト値にするとバグる」っていう、初心者が必ず踏み抜く有名な地雷があるの…。今日はその回避方法も伝授するから、心して聞いてね!💣😱

公式の「ここがわかりにくい」:評価は一度きり?

公式ドキュメントには、サラッと恐ろしいことが書いてあるよ。

デフォルト値の評価は、関数が定義された時点で、1 回だけ行われます。

「1回だけ?それがどうしたの?」って思うでしょ?
これ、要するに「関数を作った瞬間に『デフォルト値の分身』が一つだけ生成されて、その後はずーっとその『同じ分身』が使い回される」って意味なんだ。
これがリストのような「書き換え可能なもの」だと、ホラー現象が起きる原因になるんだよ…👻

1. 引数に「標準設定」を持たせる

要するにこれは「値を省略した時に自動で使われる値」の設定だよ!

関数を定義するとき、引数に = 値 を書いておくと、それがデフォルト値になるよ。
呼び出すときに値を渡せばそれが使われるし、省略すればデフォルト値が使われる便利機能だね。

🐍 サンプルコードを見る(クリックで開閉)
# messageのデフォルトを "こんにちは" に設定
def greet(name, message="こんにちは"):
    print(f"{name}さん、{message}!")

# 引数を全部指定して呼び出し
greet("AI狂い", "おはよう")

# messageを省略して呼び出し(デフォルトが発動!)
greet("Python初心者")
💻 実行結果:
AI狂いさん、おはよう!
Python初心者さん、こんにちは!

ただしルールが一つ!
デフォルト値のない引数(name)を先に、ある引数(message)を後に書かないとエラーになるよ。

2. キーワード引数:名前で指定して呼び出す

関数を呼び出すとき、引数名=値 という形で渡すこともできるよ。
これをキーワード引数と呼ぶんだ。

🐍 サンプルコードを見る(クリックで開閉)
def profile(name, age, job):
    print(f"名前: {name}, 年齢: {age}, 仕事: {job}")

# 順番通り渡す(位置引数)
profile("田中", 25, "エンジニア")

# 名前で指定して渡す(キーワード引数)
# 順番がバラバラでもOK!
profile(job="デザイナー", name="佐藤", age=30)
💻 実行結果:
名前: 田中, 年齢: 25, 仕事: エンジニア
名前: 佐藤, 年齢: 30, 仕事: デザイナー

引数がたくさんある関数を使うときは、どれがどの値か分かりやすくなるから超オススメ!

3. 【最重要】リストをデフォルト値にするな!

要するにこれは「使い回されたリストがどんどん成長しちゃうホラー現象」だよ!

ここが今回のメインディッシュ!🍛
もし、デフォルト値にリスト([])を指定するとどうなるか、実験してみよう。

🐍 恐怖の実験コード(クリックで開閉)
# リストに要素を追加する関数
# デフォルト値を空リスト [] に設定したつもり...
def add_item(item, list_box=[]):
    list_box.append(item)
    return list_box

# 1回目:普通に動く
print(add_item("リンゴ"))

# 2回目:あれ?リンゴが残ってる!?
print(add_item("ミカン"))

# 3回目:ギャーーー!増えてるーー!
print(add_item("ブドウ"))
💻 実行結果:
[‘リンゴ’]
[‘リンゴ’, ‘ミカン’]
[‘リンゴ’, ‘ミカン’, ‘ブドウ’]

なぜこうなるの?🤔
「関数が定義された時(プログラムを読み込んだ時)」に作られた [] という箱が、関数の裏側に隠し持たれていて、
引数を省略するたびにその「同じ箱」が何度も渡されるからなんだ!

4. 解決策:Noneを使え!

この問題を回避する「定石」があるよ。
デフォルト値を None にしておいて、関数の中で「もしNoneなら空リストを作る」って書くんだ。

🐍 修正版コード(クリックで開閉)
# デフォルト値を None にする
def add_item_safe(item, list_box=None):
    # ここで毎回新しいリストを作る!
    if list_box is None:
        list_box = []
        
    list_box.append(item)
    return list_box

print(add_item_safe("リンゴ"))
print(add_item_safe("ミカン"))
💻 実行結果:
[‘リンゴ’]
[‘ミカン’]

これで毎回新品の箱が用意されるようになったね!✨
リストや辞書などのミュータブル(変更可能)なオブジェクトは、絶対にデフォルト値に直接書かないこと!これ、テストに出るよ!

試験に出る!要注意ポイント

今回の範囲で、Python 3 エンジニア認定基礎試験によく出るポイントをまとめたよ!📝

① 引数の順番ルール

関数を呼び出すとき、「位置引数」は「キーワード引数」よりも先に書かないといけないよ。

# OK
func(10, b=20)

# NG(SyntaxError)
func(a=10, 20)

② デフォルト値の評価タイミング

「デフォルト値は関数定義時に1回だけ評価される」。
この言葉の意味を問う問題や、さっきのリストが増殖するコードの結果を問う問題が超頻出だよ!

💡 管理人の失敗エピソード
今の時刻を記録する関数を作ろうとして def log(time=datetime.now()): って書いたことがあるの。
そしたら、何度呼び出しても「サーバーを起動した瞬間の時刻」から一生変わらなくてパニックになったよ😱
これも「評価は1回だけ」の罠だね。正解は time=None にして中で現在時刻を取得すること!

理解度チェック!ミニクイズ

デフォルト引数の仕組み、しっかり理解できたかな?
試験レベルの問題でチェックしてみよう!🔍

次のコードを実行した結果は?
def f(x=[]):
  x.append(1)
  return x

print(f())
print(f())
  1. [1] と [1]
  2. [1] と [1, 1]
  3. エラーになる
▼ クリックで正解を表示
正解: 2. [1] と [1, 1]

解説:
デフォルト値のリスト [] は関数定義時に1回だけ作られ、共有されるよ。
だから2回目の呼び出しでは、1回目で追加された 1 が残っている状態に追加されるんだ。

関数の引数定義として正しいものはどれ?
  1. def func(a=1, b):
  2. def func(a, b=1):
  3. どっちも正しい
▼ クリックで正解を表示
正解: 2. def func(a, b=1):

解説:
デフォルト値を持たない引数(必須の引数)は、デフォルト値を持つ引数よりもに置かないといけないよ。

キーワード引数のメリットとして間違っているものは?
  1. 引数の順番を気にせずに値を渡せる
  2. どの引数に何渡しているかが読みやすくなる
  3. 存在しない引数名を指定しても自動で無視してくれる
▼ クリックで正解を表示
正解: 3. 自動で無視してくれる

解説:
定義されていない引数名をキーワード引数として渡すと、TypeError(予期しない引数です)というエラーになるよ!

まとめ:次回への引き

今回は「引数のデフォルト値と罠」について解説したよ!
「ミュータブルなデフォルト値はダメ、ゼッタイ!」これだけは夢に出るくらい唱えて覚えてね👻

次回は、引数の世界をもっと深掘り!
テーマは「関数の応用(2):特殊な引数とラムダ式」だよ。
「引数を何個でも受け取れる魔法(*args)」や、「名前のない使い捨て関数(lambda)」など、Python使いがドヤ顔で使う機能を紹介するよ!お楽しみに!👋✨

出典: Python公式チュートリアル
Copyright © 2001-2026 Python Software Foundation. Licensed under the PSF License.

よかったらシェアしてね!
  • URLをコピーしました!
目次