閉じる

Pythonのデフォルト引数とは? 引数に初期値を設定する方法

関数に渡す引数へ初期値を設定できると、呼び出し時に毎回細かい指定をしなくても済み、短く読みやすいコードになります。

Pythonではこれをデフォルト引数と呼び、柔軟かつ簡潔な関数設計を助けます。

本記事では、基本的な書き方から注意点、実用例までを初心者向けに丁寧に解説します。

Pythonのデフォルト引数とは

引数に初期値を設定できる仕組み

概要

デフォルト引数とは、関数定義のときに引数へ初期値を与えておき、呼び出し側で省略できるようにする仕組みです。

書式はdef 関数名(引数=初期値):のように、引数名の右側に=で値を指定します。

呼び出し時にその引数を渡さなければ初期値が使われ、値を渡せばその値で上書きされます。

イメージ

  • 値を渡さない場合: 「既定の設定で動く」
  • 値を渡す場合: 「必要な所だけ上書きする」

このように、1つの関数で多様な使い方に対応できます。

使うメリット 省略や再利用が楽

デフォルト引数を使うと、関数を呼ぶたびに繰り返し同じ値を渡す必要がなくなります。

また、関数のインターフェースが自己文書化され、どんな設定が標準なのかが署名から読み取れます。

結果として呼び出しが簡潔になり、再利用性が高まり、バグの混入も減らせます

微調整が必要なときだけキーワード引数で上書きできるため、柔軟性も損なわれません。

Pythonのデフォルト引数の使い方

基本の書き方 def func(arg=初期値)

デフォルト引数は引数名の後ろに= 初期値を置きます。

初期値は整数や文字列などのイミュータブル型が基本的に安全です。

Python
# 例: 冪乗を計算する関数。指数 exp は指定しなければ 2(二乗)になります。
def power(base, exp=2):
    """base の exp 乗を返す。exp を省略すると 2(二乗)。"""
    return base ** exp

# 省略時は二乗、指定時は指定の指数で計算
print(power(3))      # 3 ** 2
print(power(3, 3))   # 3 ** 3
実行結果
9
27

呼び出し 省略と上書き

省略すると初期値が使われ、渡せばその値で上書きされます

必要最低限の引数だけを指定して、使いたい時にだけ詳細を上書きするのが基本的な運用です。

Python
def greet(name="world"):
    """name を省略したら 'world' で挨拶します。"""
    return f"Hello, {name}!"

print(greet())          # 省略
print(greet("Alice"))   # 上書き
実行結果
Hello, world!
Hello, Alice!

複数のデフォルト引数

複数の引数へ初期値を設定できます。

キーワード引数と組み合わせると意図がより明確になります。

Python
def make_url(domain, path="/", scheme="https"):
    """スキームとパスを省略可能にした URL 生成関数。"""
    # path が "/" から始まっていなければ付け足す
    if not path.startswith("/"):
        path = "/" + path
    return f"{scheme}://{domain}{path}"

print(make_url("example.com"))                       # 省略
print(make_url("example.com", "/docs"))              # path 上書き
print(make_url("example.com", "docs", scheme="http"))  # 複数上書き
実行結果
https://example.com/
https://example.com/docs
http://example.com/docs

並びのルール 非デフォルトの後ろに置く

非デフォルト引数はデフォルト引数より前に並べる必要があります

逆にすると構文エラーになります。

NG例

Python
# NG: 非デフォルト引数 b がデフォルト引数 a の後ろにある
def broken(a=1, b):
    return a + b
実行結果
SyntaxError: non-default argument follows default argument

OK例

Python
def ok(a, b=1):
    return a + b

print(ok(10))     # b は初期値 1
print(ok(10, 5))  # b を上書き
実行結果
11
15

キーワード引数と併用する

キーワード引数を使うと、位置を意識せず名前で値を渡せます。

デフォルト引数と組み合わせると、必要な部分だけを狙って上書きでき、読みやすさも向上します。

Python
def format_name(first, last, sep=" ", order="FL"):
    """order は 'FL'(名→姓) または 'LF'(姓→名) を想定。sep は区切り文字。"""
    if order == "FL":
        return f"{first}{sep}{last}"
    else:
        return f"{last}{sep}{first}"

print(format_name("Taro", "Yamada"))                         # 省略: "Taro Yamada"
print(format_name("Taro", "Yamada", order="LF"))             # 名前付きで順序だけ上書き
print(format_name("Taro", "Yamada", sep="・", order="LF"))   # 複数を名前付きで上書き
実行結果
Taro Yamada
Yamada Taro
Yamada・Taro

Pythonのデフォルト引数の注意点

ミュータブル型を初期値にしない listやdictはNG

なぜNGか

list や dict のようなミュータブル(変更可能)なオブジェクトを初期値にすると、関数定義時に1度だけ生成された同じオブジェクトが使い回されてしまい、思わぬ共有が起きます

複数回呼び出しても前回の変更が残り続け、バグの原因になります。

NG例コード

Python
# NG: 同じ list が全呼び出しで共有される
def append_log(message, log=[]):
    """log に message を追加して返す(意図どおりに動かない例)。"""
    log.append(message)
    return log

print(append_log("start"))
print(append_log("step1"))
print(append_log("step2"))
実行結果
['start']
['start', 'step1']
['start', 'step1', 'step2']

意図としては毎回['stepX']のように独立したリストを期待するかもしれませんが、実際は同じリストが使われ続けています。

Noneを使う安全パターン

ミュータブルを初期値にしたい場合は、デフォルト値にはNoneを使い、関数内で新しく作るのが定石です。

これにより毎回独立したオブジェクトになります。

OK例コード

Python
def append_log_safe(message, log=None):
    """log が省略された場合は新しい list を作る安全な実装。"""
    if log is None:               # None との比較は "is" が慣用
        log = []                  # 毎回新しいリストを作成
    log.append(message)
    return log

print(append_log_safe("start"))        # ['start']
print(append_log_safe("step1"))        # ['step1'] 共有されない
print(append_log_safe("step2", []))    # 外から渡すことも可能
実行結果
['start']
['step1']
['step2']

この「Noneを使う」パターンは、list/dict/set などミュータブル全般で有効です。

デフォルト値は定義時に一度だけ評価される

仕組み

デフォルト値は関数が定義された時に1回だけ評価され、以降は同じオブジェクトが使われ続けます

そのため、現在時刻や乱数など「呼ぶたびに変わってほしい値」をデフォルトに書くと意図とズレます。

例: datetime.now() をデフォルトにすると固定される

Python
from datetime import datetime
import time

def stamped(ts=datetime.now()):
    """定義時点の時刻が固定で入る例。"""
    return ts

print("first :", stamped().isoformat())
time.sleep(2)
print("second:", stamped().isoformat())  # 2秒後でも同じ値
実行結果
first : 2024-01-01T12:00:00.000000
second: 2024-01-01T12:00:00.000000

期待と異なる場合は、次のようにNoneを使います。

Python
from datetime import datetime

def stamped_safe(ts=None):
    """呼び出しのたびに現在時刻を採用する安全版。"""
    if ts is None:
        ts = datetime.now()
    return ts

まとめ表

デフォルト値の種類安全性理由
イミュータブル0, 1.0, “ok”, (), frozenset()安全共有されても変わらないため
ミュータブル[], {}, set()危険呼び出し間で変更が共有される
変化する値datetime.now(), random.random()危険定義時に固定されてしまう

基本はイミュータブルを使い、ミュータブルやその場で変わる値は None パターンで生成する、と覚えておくと安心です。

Pythonのデフォルト引数のサンプル

あいさつ関数 nameに初期値

名前を省略したら一般的な挨拶を行い、指定したらその人に挨拶する関数です。

小さな違いをデフォルト引数で吸収すると、呼び出しがスッキリします。

Python
def greet(name="世界", polite=False):
    """
    name を省略すると '世界' に挨拶します。
    polite=True にすると丁寧な言い回しに変わります。
    """
    if polite:
        return f"こんにちは、{name}さん。"
    else:
        return f"やあ、{name}!"

# 省略(既定値を使用)
print(greet())

# 名前を上書き
print(greet("Alice"))

# 丁寧モードだけキーワードで上書き
print(greet("太郎", polite=True))
実行結果
やあ、世界!
やあ、Alice!
こんにちは、太郎さん。

税込み計算 tax_rateに初期値

消費税率をデフォルト10%(0.1)として、税抜価格に税を加算します。

税率変更や軽減税率に対応したいときだけ上書きします。

実務での通貨計算では Decimal の使用検討も有効ですが、ここでは分かりやすさを優先して小数の丸めを使います。

Python
def price_with_tax(price, tax_rate=0.1):
    """
    price に税率 tax_rate を乗じた税込価格を返します。
    小数点以下は 2 桁に丸めます(表示用途の簡易例)。
    """
    total = round(price * (1 + tax_rate), 2)  # 例: 1000 × 1.1 = 1100.0
    return total

# 既定の税率(10%)
print(price_with_tax(1000))

# 軽減税率(8%)へ上書き
print(price_with_tax(1000, tax_rate=0.08))

# 小数価格の例
print(price_with_tax(1234.56))
実行結果
1100.0
1080.0
1358.02

まとめ

デフォルト引数は、関数の使い勝手を飛躍的に高める基本テクニックです。

省略できる所は既定値で受け止め、必要な時だけキーワード引数で上書きすれば、コードは短く読みやすくなります。

ただしミュータブル型を初期値にするのは避け、Noneで受けてから生成するというルールを徹底しましょう。

さらにデフォルト値は定義時に一度だけ評価されることを理解しておけば、時刻や乱数などの落とし穴も避けられます。

今回のサンプルを土台に、自分の関数でも初期値設計を試してみてください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!