Programmingバックエンド開発者

Pythonにおける位置指定引数(positional arguments)とキーワード引数(keyword arguments)の仕組みはどのように機能するのか?関数を定義し呼び出す際の引数の順序に関する注意点は何か、そして位置指定引数のみやキーワード引数のみが必要な理由は何か?

Hintsage AIアシスタントで面接を突破

回答。

Pythonでは、関数には4種類のパラメータを宣言できます:位置指定キーワード位置指定のみキーワードのみ。これらの違いは、関数を呼び出す際の値の渡し方に影響を与えます。

パラメータの種類

  1. 位置指定(通常は最初に指定する):値は指定された順序で渡されます。
  2. キーワード:名前を通じて明示的に指定されます。
  3. 位置指定のみ/記号の前に宣言され(Python 3.8+)、名前で指定することはできません。
  4. キーワードのみ*の後に宣言され、キーでのみ指定できます。
# すべてのタイプの例 def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # エラー:a, bは位置指定のみ

注意点

  • パラメータの順序:(only-positional) / (positional-or-keyword) * (only-keyword)
  • 引数の順序が間違っている場合、SyntaxErrorまたはTypeErrorが発生します。
  • *argsは追加の位置指定引数を集め、**kwargsはキーワード引数を集めます。

トリック質問。

関数の宣言は何が違うか:

def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...

そして、これらすべての関数は位置指定引数とキーワード引数の両方で呼び出せるのは本当か?

回答:

  • def f(a, b, c):という関数は、すべての引数が必須であるため、キーワード引数のみで呼び出すことはできません。
  • 位置指定のみとして定義されていない場合、名前を通じて引数を指定することができます。
  • 関数がdef f(a, b, /, c):として宣言されている場合、abは位置指定のみで指定できます。

例:

def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10がデフォルト f(a=1, b=2, c=3) # OK # ですが: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # エラー!aとbは位置指定のみ

知識不足による実際のエラーの例


物語

ある開発者が、名前でのみパラメータを受け取るべき関数を実装したが、*を宣言するのを忘れてしまい、ユーザーが位置で誤ってパラメータを渡すことができた。その結果、ロギングが誤って行われ、追跡が難しいエラーが発生した。


物語

REST APIプロジェクトでは、引数の順序について明示的に合意が行われておらず(*argsを使い、名前による制限をしていなかった)、新しいクライアントバージョンを導入した後にリクエストが機能しなくなった。これは、argsがズレたためである。明示的な*を導入し、キーワード引数のみを指定することによって修正した。


物語

大規模な企業プロジェクトでは、関数にデフォルト値を持つ新しいパラメータが追加されたが、位置指定引数による誤った呼び出しにより、古いコードが他のパラメータに値を挿入し、データが不適切に処理された。パラメータをキーワードのみとして指定する必要があった。