Pythonでのプログラミングにおいて、関数にデータを渡す仕組みである「引数」をマスターすることは、読みやすくメンテナンス性の高いコードを書くための第一歩です。
関数は特定の処理をひとまとめにしたものですが、引数を活用することで、その処理に柔軟性を持たせることが可能になります。
本記事では、初心者の方が最初につまずきやすい基本的な位置引数から、中上級者にとっても重要な可変長引数やキーワード専用引数までを網羅的に解説します。
2026年現在のモダンな開発環境でも通用する、型ヒントを組み合わせた最新の記述方法についても触れていきます。
Pythonの引数における基本概念
Pythonの引数には、大きく分けて「関数を定義する側」と「関数を呼び出す側」の2つの視点があります。
定義側で受け取る変数を「仮引数 (parameter)」、呼び出し側で実際に渡す値を「実引数 (argument)」と呼び分けますが、一般的にはどちらも単に「引数」と表現されることが多いです。
位置引数の基本
もっともシンプルで頻繁に利用されるのが、引数を記述した順番通りに値が渡される「位置引数」です。
以下のコード例では、定義された順番に従って名前と年齢のデータが渡されます。
def introduce(name, age):
# 名前と年齢を受け取って挨拶文を表示する関数
print(f"私の名前は{name}です。年齢は{age}歳です。")
# 引数の順番通りに値を渡す
introduce("田中", 25)
私の名前は田中です。年齢は25歳です。
位置引数を使用する場合、定義された引数の数と、呼び出し時に渡す値の数が一致している必要がある点に注意してください。
もし数が合わない場合、Pythonは TypeError をスローして実行を停止します。
引数のデフォルト値(初期値)の設定
関数の定義時に、特定の引数に対してあらかじめ値を設定しておくことができます。
これを「デフォルト値」と呼び、呼び出し側でその引数を省略した場合には、この初期値が自動的に採用されます。
def greet(name, message="こんにちは"):
# message引数にデフォルト値を設定
print(f"{name}さん、{message}")
# 第二引数を省略して呼び出す
greet("佐藤")
# 第二引数を指定して呼び出す
greet("鈴木", "こんばんは")
佐藤さん、こんにちは
鈴木さん、こんばんは
デフォルト値を設定する際の重要なルールとして、デフォルト値を持つ引数は、持たない引数よりも後ろに配置しなければならないという制約があります。
例えば、def func(a=1, b): のような定義はエラーとなり、プログラムは動作しません。
可変オブジェクトをデフォルト値にする際の注意点
Python初心者から中級者がもっとも陥りやすい罠の一つが、リストや辞書などの可変 (mutable) なオブジェクトをデフォルト値に指定することです。
デフォルト値は関数が定義された時に一度だけ評価され、その後の呼び出しで共有されてしまうため、予期しない挙動を引き起こします。
def add_item(item, items=[]):
# リストをデフォルト値にすると、呼び出し間で共有される
items.append(item)
return items
print(add_item("リンゴ"))
print(add_item("バナナ"))
['リンゴ']
['リンゴ', 'バナナ']
このように、2回目の呼び出しで1回目の結果が残ってしまいます。
これを避けるためには、デフォルト値に None を指定し、関数内部で新しいリストを作成するのが定石です。
def add_item_safe(item, items=None):
# 安全なデフォルト値の設定方法
if items is None:
items = []
items.append(item)
return items
print(add_item_safe("リンゴ"))
print(add_item_safe("バナナ"))
['リンゴ']
['バナナ']
キーワード引数による明示的な指定
関数を呼び出す際に、引数名=値 という形式で値を渡す方法を「キーワード引数」と呼びます。
キーワード引数を使用すると、定義時の順番に関係なく値を渡すことができるため、コードの可読性が大幅に向上します。
def create_user(user_id, name, email):
print(f"ID: {user_id}, Name: {name}, Email: {email}")
# 引数名を指定して呼び出す(順番を入れ替えてもOK)
create_user(name="アリス", email="alice@example.com", user_id=101)
ID: 101, Name: アリス, Email: alice@example.com
特に引数の数が多い関数では、どの値が何を意味しているのかを一目で判断できるため、積極的な活用が推奨されます。
また、位置引数とキーワード引数を混ぜて使うことも可能ですが、その場合は必ず先に位置引数を記述しなければなりません。
可変長引数(*args と **kwargs)の活用
渡す引数の数が決まっていない場合や、任意の数のデータを一括で処理したい場合には「可変長引数」を使用します。
*args:複数の位置引数をタプルとして受け取る
引数名の前に * を付けることで、任意の数の位置引数をまとめてタプルとして受け取ることができます。
def calculate_sum(*args):
# argsはタプルとして扱われる
total = sum(args)
return total
print(calculate_sum(1, 2, 3, 4, 5))
15
args という名前は慣習的に使われるものですが、アスタリスクが一つあれば名前自体は任意です。
**kwargs:複数のキーワード引数を辞書として受け取る
引数名の前に ** を付けると、任意の数のキーワード引数を辞書形式で受け取ることができます。
def print_profile(**kwargs):
# kwargsは辞書として扱われる
for key, value in kwargs.items():
print(f"{key}: {value}")
print_profile(name="ボブ", age=30, city="東京")
name: ボブ
age: 30
city: 東京
これらは、ラッパー関数(他の関数を呼び出すための関数)を作成する際や、フレームワークなどの柔軟なインターフェース設計において非常に強力な武器となります。
引数の種類を制限する高度なテクニック
Python 3.8以降、より厳格に関数の使い道を制限するための機能が導入されました。
これにより、ライブラリの開発者は利用者に正しい方法で引数を渡すよう強制することができます。
位置専用引数(/)
引数リストの中に / を記述すると、それよりも前にある引数は「位置引数」としてしか渡せなくなります。
def only_positional(a, b, /):
print(a + b)
# これは正常
only_positional(10, 20)
# これはエラーになる (TypeError)
# only_positional(a=10, b=20)
引数名が将来的に変更される可能性がある場合や、引数名自体に意味がない(単なる数値計算など)場合に有効です。
キーワード専用引数(*)
引数リストの中に * を記述すると、それよりも後ろにある引数は必ずキーワード引数として指定しなければなりません。
def only_keyword(name, *, age):
print(f"{name} is {age} years old.")
# これは正常
only_keyword("チャーリー", age=40)
# これはエラーになる (TypeError)
# only_keyword("チャーリー", 40)
重要なオプション引数を設定ミスで渡し忘れるのを防ぐために、非常に役立つ設計手法です。
型ヒントを用いたモダンな引数の定義
2026年現在のPython開発では、引数に型ヒントを付与することがデファクトスタンダードとなっています。
型ヒントを記述することで、エディタの補完機能が強化され、静的解析ツールによるエラーチェックが可能になります。
from typing import List, Optional
def process_data(names: List[str], retry_count: int = 3, logger_name: Optional[str] = None) -> bool:
# namesは文字列のリスト、retry_countは整数、logger_nameは文字列またはNone
print(f"Processing {len(names)} items...")
return True
process_data(["Alice", "Bob"], retry_count=5)
型ヒントは実行時の動作を強制するものではありませんが、コードの可読性と堅牢性を高めるために不可欠な要素です。
特にチーム開発や大規模なプロジェクトでは、引数の型が明示されているだけでデバッグの工数が劇的に削減されます。
引数のアンパック(展開)
リストや辞書に格納されているデータを、関数の引数として展開して渡すことも可能です。
これを「アンパック」と呼び、呼び出し時に * または ** を使用します。
def add(a, b, c):
return a + b + c
nums = [1, 2, 3]
# リストを展開して渡す
print(add(*nums))
params = {"a": 10, "b": 20, "c": 30}
# 辞書を展開して渡す
print(add(**params))
6
60
外部のAPIから取得したデータや、設定ファイルから読み込んだ辞書をそのまま関数に流し込む際に非常に便利です。
良い引数設計のためのベストプラクティス
優れた関数を作成するためには、引数の設計に一貫性を持たせることが重要です。
まず、引数の数は多くなりすぎないようにしましょう(目安として5つ以内)。
もし引数が多くなりすぎる場合は、関連するデータをクラスやデータクラス(dataclass)にまとめることを検討してください。
また、デフォルト値の濫用は避け、本当に「省略しても問題ない」ものだけに設定するのがコツです。
さらに、引数の順番は「もっとも重要なもの」を先頭にし、次に「変更頻度が高いもの」を配置するように心がけましょう。
これにより、利用者が関数を直感的に使いこなせるようになります。
まとめ
Pythonの引数は、位置引数というシンプルな基本から、可変長引数や各種制限オプションまで、非常に多彩な機能を備えています。
これらの機能を適切に使い分けることで、関数のインターフェースを明確にし、バグの少ないプログラムを構築することができます。
特に、デフォルト値に可変オブジェクトを使用しないことや、型ヒントを活用して意図を明確にすることは、実務レベルでは必須の知識です。
本記事で紹介したテクニックを日々のコーディングに取り入れ、より高品質なPythonコードを目指してください。
まずは小さな関数から、キーワード引数や型ヒントを意識して書いてみることから始めてみましょう。
