Pythonの関数に値を渡す方法は、プログラムの読みやすさと正確さを左右する重要な基礎です。
本記事では、位置引数とキーワード引数の違いと使い分け、また両者の組み合わせ時のルールやエラーの読み方まで、動くサンプルと共にやさしく解説します。
戻り値やモジュールは別記事で扱います。
Pythonの引数の基本(初心者向け)
引数とは何か
引数は、関数に処理対象のデータや条件を渡すための値です。
定義側の「名前」と呼び出し側の「値」を区別しておくと理解が進みます。
用語の整理(パラメータと引数)
パラメータ(仮引数)はdef
で定義する名前、引数(実引数)は呼び出し時に渡す具体的な値を指します。
用語 | どちら側か | 意味 | 例 |
---|---|---|---|
パラメータ(仮引数) | 定義側 | 関数内で使う受け取り用の名前 | def add(x, y): ... の x , y |
引数(実引数) | 呼び出し側 | 実際に渡す値 | add(2, 3) の 2 , 3 |
「パラメータ=ラベル」「引数=値」と覚えると混乱しにくいです。
関数にデータを渡す仕組み
Pythonでは「オブジェクトへの参照」が関数に渡されます。
ミュータブル(変更可能)なオブジェクトは関数内での変更が呼び出し元にも反映される一方で、ローカル変数に新しい値を再代入しても呼び出し元の変数は変わりません。
# ミュータブルなオブジェクト(list)は関数内の変更が呼び出し元に影響する例
def append_marker(seq):
# ここでは参照先のリスト自体を変更している(ミューテーション)
seq.append("X")
print("[append_marker] 内部のseq:", seq)
# イミュータブル(数値など)は再代入するとローカルだけが変化する例
def reassign(num):
# numに新しい整数オブジェクトを紐づける(呼び出し元の変数とは別物)
num = 999
print("[reassign] 関数内のnum:", num)
items = [1, 2]
print("[main] 呼び出し前のitems:", items)
append_marker(items) # ミューテーションが外にも影響
print("[main] 呼び出し後のitems:", items)
n = 10
print("[main] 呼び出し前のn:", n)
reassign(n) # 再代入はローカルのみ
print("[main] 呼び出し後のn:", n)
[main] 呼び出し前のitems: [1, 2]
[append_marker] 内部のseq: [1, 2, 'X']
[main] 呼び出し後のitems: [1, 2, 'X']
[main] 呼び出し前のn: 10
[reassign] 関数内のnum: 999
[main] 呼び出し後のn: 10
注意点
「参照が渡される」ため、関数内でのミュータブルなオブジェクトの変更(appendやremoveなど)は呼び出し元にも影響します。
意図せず変更したくない場合は、list(arg)
やarg.copy()
でコピーしてから操作すると安心です。
defでの引数名と呼び出しの関係
定義側の名前に位置またはキーワードで値を対応づけます。
どちらの方法でも「最終的にパラメータ名に値が入る」点は同じです。
def greet(name, age):
print(f"こんにちは、{name}さん。{age}歳ですね。")
# 位置引数で対応(順番が重要)
greet("Taro", 20)
# キーワード引数で対応(名前で対応)
greet(age=25, name="Hanako")
こんにちは、Taroさん。20歳ですね。
こんにちは、Hanakoさん。25歳ですね。
位置引数の使い方
順番で値を渡す
位置引数はパラメータの並び順に従って値を渡す方法です。
数が少なく、順番が直感的なときに向いています。
def rectangle_area(width, height):
"""長方形の面積を計算する(width×height)"""
return width * height
area = rectangle_area(3, 5) # width=3, height=5
print("面積:", area)
面積: 15
順番を入れ替えると意味が変わるため、似た型が続くと誤りに気づきにくい点に注意します。
必須で省略不可
パラメータにデフォルト値を与えていない場合、位置引数は必須です。
足りないとTypeError
になります。
def rectangle_area(width, height):
return width * height
print(rectangle_area(3, 5)) # OK
print("以下はエラーになる呼び出し例")
# print(rectangle_area(3)) # 実際に実行するとTypeError
実行結果(エラーメッセージ例)
15
以下はエラーになる呼び出し例
TypeError: rectangle_area() missing 1 required positional argument: 'height'
関数呼び出しの書き方のコツ
位置引数は「自然な順序」で意味が想像しやすいときに使うのがコツです。
数が増えたり、似た値が並ぶときはキーワードの併用を検討します。
def paint(r, g, b):
"""RGBで色を指定して表示するデモ"""
print(f"RGB = ({r}, {g}, {b})")
# 位置引数のみ(順番を間違えると色が変わる)
paint(255, 0, 0) # 赤
paint(0, 255, 0) # 緑
# キーワードでの明示(順番の取り違えを防げる)
paint(r=0, b=255, g=0) # 青(順序が入れ替わってもOK)
RGB = (255, 0, 0)
RGB = (0, 255, 0)
RGB = (0, 0, 255)
位置引数だけに頼ると、意図しない順序ミスを見逃しやすくなります。
不安なときはキーワード引数を使いましょう。
キーワード引数の使い方
名前で値を渡す
キーワード引数は「パラメータ名=値」の形で渡す方法です。
関数の意図が読み取りやすくなります。
def show_profile(name, age, city):
print(f"名前:{name}, 年齢:{age}, 居住地:{city}")
# キーワードで明示
show_profile(name="Taro", age=20, city="Osaka")
名前:Taro, 年齢:20, 居住地:Osaka
順序に依存しない
キーワード引数は指定の順序に依存しません。
名前で一致づけされるため、並び順を気にせず書けます。
def show_profile(name, age, city):
print(f"名前:{name}, 年齢:{age}, 居住地:{city}")
# 並べ替えても同じ結果
show_profile(city="Nagoya", name="Hanako", age=25)
名前:Hanako, 年齢:25, 居住地:Nagoya
間違えやすい点
存在しない名前を指定するとTypeError
になります。
def show_profile(name, age, city):
print(f"名前:{name}, 年齢:{age}, 居住地:{city}")
# スペルミス: nam ではなく name
# show_profile(nam="Taro", age=20, city="Osaka") # 実行するとTypeError
実行結果(エラーメッセージ例)
TypeError: show_profile() got an unexpected keyword argument 'nam'
可読性が上がる指定方法
ブール値や数値など、意味が曖昧になりやすい引数はキーワードで明示すると読みやすくなります。
サンプルコード(前→後)
def create_user(name, age, country, active=False):
print(f"name={name}, age={age}, country={country}, active={active}")
# (前) 位置だけだと True や数値の意味が曖昧
create_user("Taro", 30, "JP", True)
# (後) キーワードで明示して読みやすく
create_user(name="Taro", age=30, country="JP", active=True)
name=Taro, age=30, country=JP, active=True
name=Taro, age=30, country=JP, active=True
同じ結果でも「後」のほうが意図が伝わりやすく、バグを防ぎやすいです。
位置引数とキーワード引数の組み合わせ
指定の順序ルール(位置引数→キーワード引数)
関数呼び出しでは位置引数を先に書き、その後にキーワード引数を書くというルールがあります。
キーワードの後に位置引数を書くと構文エラーです。
def order(item, quantity, unit_price):
total = quantity * unit_price
print(f"商品:{item}, 数量:{quantity}, 単価:{unit_price}, 合計:{total}")
# 有効な呼び出し
order("Apple", 2, unit_price=150) # 位置→位置→キーワード
order("Banana", quantity=3, unit_price=120) # 位置→キーワード→キーワード
# 無効な呼び出し(キーワードの後に位置引数)
# order(item="Orange", 5, unit_price=100) # 構文エラー: positional argument follows keyword argument
商品:Apple, 数量:2, 単価:150, 合計:300
商品:Banana, 数量:3, 単価:120, 合計:360
キーワードを使い始めたら、その後は位置引数を書かないと覚えるとシンプルです。
同じ引数の重複指定はエラー
1つのパラメータに2つの値を与えるとTypeError
になります。
位置で1回、キーワードで1回のような「二重指定」は禁止です。
def greet(name, age):
print(f"{name}さん({age}歳) ようこそ")
greet("Taro", 20) # OK
# greet("Taro", name="Taro") # NG: multiple values for argument 'name'
Taroさん(20歳) ようこそ
エラーメッセージ例
TypeError: greet() got multiple values for argument 'name'
よくあるエラー(TypeError)と対処
エラーメッセージを日本語に直して理解すると原因が見つけやすいです。
代表例をまとめます。
メッセージの一部 | 意味 | 対処 |
---|---|---|
missing N required positional argument(s) | 必須の位置引数が足りない | 値を追加する、または設計を見直す |
got an unexpected keyword argument ‘x’ | 存在しないキーワードを指定した | スペルミス修正、関数のパラメータ名を確認 |
got multiple values for argument ‘x’ | 同じ引数に2回値を渡した | どちらか一方に統一 |
positional argument follows keyword argument | キーワードの後に位置引数を書いた | 引数の並び順を修正 |
まとめて確認できるサンプル
def f(a, b):
print(f"a={a}, b={b}")
print("[不足する例]")
try:
f(1) # b が足りない
except Exception as e:
print(type(e).__name__ + ":", e)
print("[未知のキーワード]")
try:
f(1, c=3) # c は定義されていない
except Exception as e:
print(type(e).__name__ + ":", e)
print("[重複指定]")
try:
f(1, a=2) # a に2回値を渡している
except Exception as e:
print(type(e).__name__ + ":", e)
[不足する例]
TypeError: f() missing 1 required positional argument: 'b'
[未知のキーワード]
TypeError: f() got an unexpected keyword argument 'c'
[重複指定]
TypeError: f() got multiple values for argument 'a'
エラー文に出てくるパラメータ名(例:'b'
)を手がかりに、定義のdef
を必ず見直しましょう。
まとめ
本記事では、位置引数は「順番で渡す」・キーワード引数は「名前で渡す」という基本と、両者の組み合わせ時のルール(位置→キーワード)を、実行例とともに確認しました。
必要最小限の位置引数に抑えつつ、意味が曖昧になりやすい値はキーワードで明示すると、読みやすさとバグの予防に効果的です。
TypeErrorや構文エラーはメッセージを素直に読むことで原因に素早くたどり着けます。
まずは小さな関数から、位置とキーワードを使い分ける練習を積み上げていきましょう。