このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】位置専用引数とキーワード専用引数

位置専用引数とキーワード専用引数

 Python 3.8以降、関数の引数に関してさらに厳密な制御が可能になりました。その中でも「位置専用引数」と「キーワード専用引数」は、引数の受け渡し方法を明確に区別するための重要な機能です。位置専用引数は、関数呼び出し時にキーワード指定できず、必ず位置に従って値が割り当てられる一方、キーワード専用引数は、必ずキーワード引数として渡さなければならず、順序に依存しません。ここでは、その基本概念、定義方法、そして実践例を具体的なコードや表を交えて詳しく解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.基本概念

1.1. 引数の種類と順序の規則

Python関数の引数には、いくつかの種類があります。特に、以下の点に注意します。

  • 位置専用引数: 関数定義時に、仮引数の後ろにスラッシュ(/)を記述すると、それ以前の引数は位置専用引数となり、呼び出し時にキーワード指定できません。
  • 通常の引数: 位置引数とキーワード引数の両方で渡すことが可能です。
  • キーワード専用引数: 関数定義時に、アスタリスク(*)の後ろに記述された引数は、キーワード専用引数となり、必ずキーワード指定で渡さなければなりません。
  • 可変長引数: さらに、*args(位置引数の可変長)や**kwargs(キーワード引数の可変長)を使うことも可能です。

1.2. 引数の並び順

関数定義時の引数は、以下の順序で記述する必要があります。

def 関数名(位置専用引数, /, 通常の引数, *, キーワード専用引数, **kwargs):
    文...

解説

  • / より左側は位置専用引数であり、キーワード指定できません。
  • * より右側はキーワード専用引数となり、呼び出し時には必ず引数名を指定する必要があります。
  • 可変長引数(*args**kwargs)は、通常の引数の中に含めることもできますが、ここでは基本的な使い分けに注目します。

2.Pythonにおける位置専用引数とキーワード専用引数の定義

2.1. 位置専用引数の定義

 位置専用引数は、引数リストの最初に / を配置することで定義します。例えば、以下の関数では、item は位置専用引数として定義されています。

def menu_item(item, /, quantity, *, price):
    """
    座席メニューの注文情報を表示する関数
    
    Parameters:
      item     : 料理の名前(位置専用引数、キーワード指定不可)
      quantity : 注文数(通常の引数、位置またはキーワード指定可能)
      price    : 料理の価格(キーワード専用引数、必ずキーワード指定)
    """
    print("Item    :", item)
    print("Quantity:", quantity)
    print("Price   :", price)

解説

  • item の後ろにスラッシュ(/)を記述することで、item は位置専用引数となり、関数呼び出し時に必ず位置指定で渡さなければなりません。
  • price の前にアスタリスク(*)があり、それ以降の引数はキーワード専用引数となるため、price はキーワード指定で渡す必要があります。
  • quantity は通常の引数であり、位置指定でもキーワード指定でも渡すことができます。

2.2. キーワード専用引数の呼び出し例

上記の menu_item 関数を正しく呼び出す例は以下の通りです。

# 正しい呼び出し例:
menu_item("Pasta", 2, price=15)

実行結果

# 正しい呼び出し例:
menu_item("Pasta", 2, price=15)
Item    : Pasta
Quantity: 2
Price   : 15

解説

  • "Pasta" は位置専用引数 item に割り当てられ、2 は通常引数 quantity に割り当てられます。
  • price=15 はキーワード専用引数として、名前を明示して渡されています。

2.3. 誤った呼び出し例とエラー

位置専用引数はキーワード指定できないため、以下のように呼び出すとエラーが発生します。

# 誤った呼び出し例:位置専用引数をキーワード指定している
menu_item(item="Pasta", quantity=2, price=15)  # これではエラーになる

実行結果

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 2
      1 # 誤った呼び出し例:位置専用引数をキーワード指定している
----> 2 menu_item(item="Pasta", quantity=2, price=15)

TypeError: menu_item() got some positional-only arguments passed as keyword arguments: 'item'

解説

item は位置専用引数なので、キーワードで渡そうとすると TypeError が発生します。

3.複合的な例:可変長引数との併用

 位置専用引数やキーワード専用引数は、可変長引数(*args, **kwargs)と組み合わせて使うことも可能です。以下は、位置専用引数、通常の引数、キーワード専用引数、そして可変長キーワード引数を含む複雑な関数定義の例です。

def describe_order(a, /, b, *args, c, **kwargs):
    """
    複数の引数を受け取り、注文内容を詳細に表示する関数。
    
    Parameters:
      a      : 位置専用引数(必ず位置指定)
      b      : 通常の引数(位置またはキーワード指定可能)
      *args  : 任意の数の位置引数をタプルとして受け取る
      c      : キーワード専用引数(必ずキーワード指定)
      **kwargs : 任意の数のキーワード引数を辞書として受け取る
    """
    print("a:", a)
    print("b:", b)
    print("Additional positional arguments (args):", args)
    print("c (keyword-only):", c)
    print("Additional keyword arguments (kwargs):", kwargs)

# 呼び出し例
describe_order(1, 2, 3, 4, c=5, x=6, y=7)

実行結果

a: 1
b: 2
Additional positional arguments (args): (3, 4)
c (keyword-only): 5
Additional keyword arguments (kwargs): {'x': 6, 'y': 7}

解説

  • この関数では、a が位置専用引数で、呼び出し時には必ず最初に位置指定で渡されます。
  • b は通常の引数で、位置指定またはキーワード指定が可能ですが、ここでは位置引数として渡されます。
  • *args により、3 と 4 がタプル (3, 4) として受け取られます。
  • c はキーワード専用引数なので、必ず c=5 のようにキーワードで指定します。
  • **kwargs によって、その他のキーワード引数が辞書として受け取られ、{'x': 6, 'y': 7} となります。

【表:位置専用引数とキーワード専用引数のまとめ】

種類定義方法特徴
位置専用引数def func(a, /, ...):/ より左側の引数は、関数呼び出し時にキーワード指定できず、位置指定のみ。
通常の引数def func(..., b, ...):位置指定でもキーワード指定でも渡すことが可能。
キーワード専用引数def func(..., *, c, ...):* の後ろに記述された引数は、必ずキーワード指定で渡す必要がある。
可変長位置引数 (*args)def func(*args):複数の位置引数をタプルとして受け取る。
可変長キーワード引数(**kwargs)def func(**kwargs):複数のキーワード引数を辞書として受け取る。

まとめ

 位置専用引数とキーワード専用引数を正しく使い分けることにより、関数の呼び出し方法を明確に制御でき、意図しない引数の誤割り当てを防ぐことができます。

  • 位置専用引数は、関数定義時にスラッシュ(/)を用いて指定し、キーワード指定で渡すことができないため、呼び出し時に順番が非常に重要です。
  • キーワード専用引数は、アスタリスク(*)の後に記述され、必ずキーワードで指定して渡す必要があります。
  • これらに加えて、可変長引数(*args**kwargs)を組み合わせることで、非常に柔軟な関数呼び出しが可能となります。

 これらの概念と使い方を正確に理解することで、堅牢で保守性の高い関数を設計し、プログラム全体の再利用性を向上させることができます。