概要(デフォルト引数は「省略しても動くための既定値」)
デフォルト引数は、関数定義の引数に初期値を設定しておき、呼び出し時にその引数を省略できる仕組みです。使いどころは「ほとんどのケースで同じ値」「オプション的な設定」。柔軟にしつつ、呼び出しを短くできます。
def greet(name="ゲスト"):
return f"こんにちは、{name}さん!"
print(greet()) # 省略 → "ゲスト"
print(greet("花子")) # 上書き → "花子"
Python基本構文と引数の並び(ここが重要)
必須→デフォルトの順で並べる
「必須引数」を前に、「デフォルト引数」を後ろに並べます。これは文法ルールで、守らないとエラーになります。
def format_price(amount, currency="JPY", with_tax=False):
total = round(amount * (1.1 if with_tax else 1))
return f"{currency} {total}"
print(format_price(350)) # JPY 350
print(format_price(350, with_tax=True)) # JPY 385
Python位置引数・キーワード引数との併用
デフォルト引数は「省略可能」ですが、必要ならキーワード指定で明示的に渡すと読みやすくなります。
def power(x, exp=2):
return x ** exp
print(power(3)) # 9(省略)
print(power(x=3, exp=4)) # 81(明示)
Python位置限定/キーワード限定との組み合わせ
インターフェースを堅牢にしたいとき、「/」の左は位置のみ、「*」の右はキーワードのみにできます。
def scale(x, /, factor=1.0, *, rounding=None):
y = x * factor
return round(y, rounding) if rounding is not None else y
print(scale(10, 0.3)) # 3.0(xは位置のみ)
print(scale(10, 0.3, rounding=2)) # 3.00(roundingはキーワードのみ)
Python評価タイミングとミュータブルの罠(最重要ポイントの深掘り)
デフォルト値は「定義時に一度だけ」評価される
デフォルト値は def が実行された瞬間に一度だけ作られ、以降の呼び出しで使い回されます。時刻やランダムなど「呼ぶたびに変わってほしい値」をデフォルトに直接書くと意図とズレます。
import datetime
def timestamp(ts=datetime.datetime.now()): # NG 例
return ts # 定義時の時刻で固定される
Python必要なら None を使って「呼び出し時に初期化」します。
def timestamp(ts=None):
if ts is None:
ts = datetime.datetime.now()
return ts
Pythonミュータブル(list/dict)をデフォルトにしない
list や dict をデフォルトにすると、呼び出し間で「同じオブジェクト」が使い回され、意図せず蓄積されます。
def append_item(item, bag=[]): # NG
bag.append(item)
return bag
print(append_item(1)) # [1]
print(append_item(2)) # [1, 2] ← 前回の中身が残る
Python必ず None を使って「その場で新規生成」しましょう。
def append_item(item, bag=None):
if bag is None:
bag = []
bag.append(item)
return bag
Python設計の勘所(柔軟性・安全性・可読性)
オプションは「ブール・列挙・値」できれいに表現
設定フラグは with_tax=True のようにブールで、選択肢は文字列や Enum で。曖昧さを減らします。
def format_text(text, *, case="lower"):
s = text.strip()
if case == "lower": return s.lower()
if case == "upper": return s.upper()
return s
Pythonデフォルトは「現実の既定値」を選ぶ
一番よく使う値をデフォルトにするほど、呼び出しが短く自然になります。逆に議論の余地がある“危険な既定値”は避ける(例:安全機能を既定でオフにしない)。
None を「未指定」の合図にする
値が意味を持つケースでは、None を「未指定」にし、渡されたときだけ上書きするパターンが強いです。
def connect(host="localhost", port=None):
port = 443 if port is None else port
return (host, port)
Python実用テクニック(ログ・時間・関数の前設定)
ログ関数:レベルや時刻の既定値
import datetime
def log(msg, *, level="INFO", now=None):
ts = now or datetime.datetime.now()
print(f"{ts:%Y-%m-%d %H:%M:%S} [{level}] {msg}")
log("起動") # 既定レベル・現在時刻
log("失敗", level="ERROR") # レベル上書き
Python重みや税率など「業務既定値」を持つ
def revenue(orders, *, tax_rate=0.1):
total = sum(o["qty"] * o["price"] for o in orders)
return round(total * (1 + tax_rate))
print(revenue([{"qty":2,"price":350}])) # tax 10% 既定
print(revenue([{"qty":2,"price":350}], tax_rate=0.08)) # 8% に変更
Python関数の「事前設定」用ラッパ(部分適用もどき)
def render_button(label, *, cls="primary", disabled=False):
return f'<button class="{cls}" disabled="{disabled}">{label}</button>'
# 二次関数化せずとも、既定値で“事前設定”風に使える
print(render_button("OK")) # class=primary
print(render_button("Cancel", cls="secondary", disabled=True))
Pythonつまずきやすいポイントと対策(順序・型・テスト)
引数の並び順を守る(必須→デフォルト→キーワード限定)
間違えると SyntaxError/TypeError。API を長期運用するなら、/ と * で「位置限定・キーワード限定」を活用して破壊的変更を防ぎます。
def api(user_id, /, *, page=1, limit=20):
return (user_id, page, limit)
Python型ヒントで「未指定」を表現
Optional(Union with None)で意図を明確にします。
from typing import Optional
def search(query: str, *, limit: Optional[int] = None) -> list[str]:
# limit が None なら全件の上限を使う、など
...
Pythonテストでは「既定」と「上書き」をそれぞれ検証
- 既定値が期待通りに働くか
- 上書き指定が優先されるか
- ミュータブルの罠に陥っていないか(連続呼び出し)
例題で身につける(定番から一歩先まで)
例題1:デフォルトとキーワードの併用
def power(x, exp=2, *, mod=None):
y = x ** exp
return y % mod if mod else y
print(power(3)) # 9
print(power(3, 3)) # 27
print(power(3, mod=5)) # 4(9 % 5)
Python例題2:None 初期化で時刻とリストを安全に
import datetime
def add_event(title, when=None, tags=None):
when = when or datetime.datetime.now()
tags = tags or []
return {"title": title, "when": when, "tags": tags}
e1 = add_event("meet")
e2 = add_event("meet", tags=["work"])
print(e1["tags"], e2["tags"]) # [], ['work'](共有されない)
Python例題3:位置限定+キーワード限定で安全な API
def resize(width, height, /, *, keep_ratio=True, background="black"):
return {"w": width, "h": height, "keep": keep_ratio, "bg": background}
print(resize(640, 480)) # 既定適用
print(resize(640, 480, background="white")) # キーワードで上書き
Python例題4:業務既定値の集中管理
DEFAULTS = {"currency": "JPY", "tax_rate": 0.1}
def invoice(amount, *, currency=DEFAULTS["currency"], tax_rate=DEFAULTS["tax_rate"]):
total = round(amount * (1 + tax_rate))
return f"{currency} {total}"
print(invoice(1000)) # JPY 1100
print(invoice(1000, tax_rate=0.08)) # JPY 1080
Pythonまとめ
- デフォルト引数は「省略できる入口」。必須→デフォルトの順で並べ、キーワード指定で読みやすく。
- デフォルト値は定義時に一度だけ評価。時刻・乱数・ミュータブルは None で受けて「呼び出し時に初期化」する。
- / と * で位置限定・キーワード限定を使い、API を堅牢に保つ。
- オプションはわかりやすい既定値を選び、None を未指定の合図に。型ヒントで意図を明確化。
- 既定・上書き・連続呼び出しのテストで、ミュータブルの罠と評価タイミングの問題を早期に潰す。
実務で効くのは「安全な既定」「明示的な上書き」「未指定=None」の三本柱。これを癖にすると、あなたの関数は使いやすく、事故らない。
