Python 3.8から、関数定義の際に引数リストの中でスラッシュ / を使用できるようになりました。
これは**「位置専用引数(Positional-Only Arguments)」**を定義するための構文です。この記法を使うと、特定の引数に対して「キーワード引数としての呼び出し」を禁止し、「位置引数(値の順番)」でのみ値を渡すよう強制できます。
組み込み関数の len(obj) や pow(x, y) のように、引数の名前よりも「順番」が重要な関数を定義する際に役立ちます。
この記事では、位置専用引数の書き方と、そのメリットについて解説します。
位置専用引数の書き方
関数定義の引数リストにおいて、/(スラッシュ)を配置すると、それより左側にある引数はすべて「位置専用」となります。
構文:
def 関数名(位置専用1, 位置専用2, /, 通常引数):
# 処理
具体的な使用例
例として、年、月、日を受け取ってフォーマットされた日付文字列を返す関数を作成します。日付のようなデータは、year=2025 と書くよりも 2025, 11, 20 と順番に書くほうが自然な場合があります。
def format_date(year, month, day, /, separator="-"):
"""
年、月、日を位置引数で受け取り、指定された区切り文字で結合する
"""
return f"{year}{separator}{month:02}{separator}{day:02}"
# --- 正しい呼び出し方 ---
# year, month, day は位置引数として渡す(/ の左側にあるため)
date_str = format_date(2025, 11, 20)
print(f"日付: {date_str}")
# separator は通常の引数なので、キーワード指定が可能
date_slash = format_date(2025, 11, 20, separator="/")
print(f"スラッシュ区切り: {date_slash}")
実行結果:
日付: 2025-11-20
スラッシュ区切り: 2025/11/20
エラーになる呼び出し方
/ の左側にある引数を、キーワード引数として指定しようとすると TypeError が発生します。
# エラー例: 位置専用引数をキーワードで指定
# format_date(year=2025, month=11, day=20)
# TypeError: format_date() got some positional-only arguments passed as keyword arguments: 'year', 'month', 'day'
これにより、呼び出し側に対して「この引数は順番で渡してください」という制約を強制できます。
なぜ位置専用引数を使うのか(メリット)
一見すると不便な制約に見えるかもしれませんが、ライブラリ開発やAPI設計においては以下のようなメリットがあります。
- 引数名を自由に変更できる 呼び出し側が引数名(
yearなど)に依存しないため、関数内部の実装変更に合わせて引数名をリファクタリングしても、利用者のコード(format_date(2025, ...))を壊すことがありません。 - キーワード引数との競合回避
**kwargs(可変長キーワード引数)を使用する場合、位置引数の名前とkwargsのキーが重複するのを防ぐことができます。 - 可読性の向上 引数の意味が自明な場合(例:
len(obj)のobj)、名前を書かせない方がコードがすっきりします。
全種類の引数の組み合わせ
Pythonでは、「位置専用」「通常(位置またはキーワード)」「キーワード専用」の3種類を混在させることができます。
順序は以下の通りです。
def f(位置専用, /, 通常, *, キーワード専用):
def complex_function(a, b, /, c, *, d):
print(a, b, c, d)
# a, b : 位置指定のみ
# c : 位置でもキーワードでもOK
# d : キーワード指定のみ
complex_function(1, 2, 3, d=4) # OK
complex_function(1, 2, c=3, d=4) # OK
# complex_function(a=1, 2, 3, d=4) # NG (aは位置専用)
# complex_function(1, 2, 3, 4) # NG (dはキーワード専用)
まとめ
- 関数定義の引数リストにある
/は、それより左側の引数を「位置専用」にします。 - 位置専用引数は、呼び出し時に
引数名=値の形式を使えず、値の順番で渡す必要があります。 - 引数名の変更による影響をなくしたい場合や、引数の意味が自明な場合に有効な機能です。
