やっほー!国内の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回だけ作られ、共有されるよ。
だから2回目の呼び出しでは、1回目で追加された 1 が残っている状態に追加されるんだ。
関数の引数定義として正しいものはどれ?
▼ クリックで正解を表示
def func(a, b=1):
解説:
デフォルト値を持たない引数(必須の引数)は、デフォルト値を持つ引数よりも前に置かないといけないよ。
キーワード引数のメリットとして間違っているものは?
▼ クリックで正解を表示
解説:
定義されていない引数名をキーワード引数として渡すと、TypeError(予期しない引数です)というエラーになるよ!
まとめ:次回への引き
今回は「引数のデフォルト値と罠」について解説したよ!
「ミュータブルなデフォルト値はダメ、ゼッタイ!」これだけは夢に出るくらい唱えて覚えてね👻
次回は、引数の世界をもっと深掘り!
テーマは「関数の応用(2):特殊な引数とラムダ式」だよ。
「引数を何個でも受け取れる魔法(*args)」や、「名前のない使い捨て関数(lambda)」など、Python使いがドヤ顔で使う機能を紹介するよ!お楽しみに!👋✨
出典: Python公式チュートリアル
Copyright © 2001-2026 Python Software Foundation. Licensed under the PSF License.






