検索
連載

[Python入門]関数の引数Python入門(1/3 ページ)

位置引数やキーワード引数、パラメーターのデフォルト引数値、可変長引数の扱い方など、Pythonにおける関数の引数について見てみよう。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Python入門」のインデックス

連載目次

* 本稿は2019年5月21日、2022年6月17日に公開/改訂された記事を、Python 3.12.0で動作確認したものです(確認日:2023年10月16日)。


 前回はPythonの関数の基礎知識を紹介した。関数呼び出しの方法、ユーザー定義関数の定義方法などがそうだ。今回は、位置指定引数とキーワード引数、パラメーターにデフォルト引数値を持たせる方法、可変長引数など、関数の引数について少々詳しく見ていこう。

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

 関数呼び出し時に引数(実引数)を渡すことを考えてみる。まずはサンプルの関数を作っておく。

def myfunc(param1, param2, param3):
    return f'param1: {param1}, param2: {param2}, param3: {param3}'

サンプルの関数「myfunc」

 myfunc関数にはパラメーターが3つある。戻り値はそれらを「param1: ……, param2: ……, param3: ……」という文字列に埋め込んだものとなる。これは実引数がどのパラメーターに渡されたかを調べるための関数だ。

位置引数

 では、この関数を呼び出してみよう。

print(myfunc(1, 2, 3))

myfunc関数を呼び出してみる

 これまでに説明してきたやり方だと、上のような呼び出し方をする。実際に実行すると、次のように実引数が埋め込まれた文字列が返される。

実行結果
実行結果

 1つ目のmyfunc関数呼び出しの第1引数の「1」、第2引数の「2」、第3引数の「3」はmyfunc関数の定義で示されている第1パラメーターの「param1」、第2パラメーターの「param2」、第3パラメーターの「param3」へ順番に渡されていることが上の出力から分かるはずだ。

 このように、関数呼び出し時に「引数を渡した位置によって、どのパラメーターがその値を受け取るかが決定される」ような引数(の渡し方)を「位置引数」(positional argument)と呼ぶ。

位置引数
位置引数

 引数の位置に気を付ければ、特に問題なく引数を関数に渡せる。しかし、場合によっては「この値はこのパラメーターの値だよ」と指定できると便利なこともある(特に後述する「関数が多数のパラメーターを持ち、それらがデフォルト値を持っている」場合)。このときに使うのが「キーワード引数」だ。

キーワード引数

 今述べたように、「キーワード引数」は関数呼び出し時に「実引数をどのパラメーターに渡すべきか」を「パラメーター名=実引数の値」のようにして指定するものだ。

キーワード引数
キーワード引数

 このとき、関数定義のパラメーターリストに並べた順番通りに引数を渡す必要はない。実際に試してみよう。ここではparam3、param2、param1の順番に引数をパラメーターに渡している。

print(myfunc(param3=1, param2='string', param1=0.5))

キーワード引数の使用例

 これを実行すると、以下のようになる。「パラメーター名=実引数の値」として渡したときに指定したそれぞれのパラメーターに対応する値が渡されているのが分かる。

キーワード引数を指定した場合の実行結果
キーワード引数を指定した場合の実行結果

 このとき、関数のパラメーターリストにあるパラメーターの名前とキーワードを一致させる必要があることには注意しよう。パラメーターリストにないキーワードを指定することはできない(ただし、後述する「可変長キーワード引数」を使うことで、任意の「キーワード=実引数の値」という組を渡せるようになる)。

位置引数とキーワード引数の混在

 位置引数とキーワード引数は混在させることも可能だ。ただし、このときには位置引数を先に置き、キーワード引数はその後で指定する必要がある。以下に適切な引数の渡し方と、エラーとなる引数の渡し方を示す。

print(myfunc(1, param3='param3', param2=2))  # 正しい
print(myfunc(param3='param3', 2, 1))  # エラー

位置引数とキーワード引数を混在させる

 実行すると次のように、2つ目の呼び出しではエラーが発生する。

2つ目の呼び出しで「位置引数がキーワード引数の後にある」というエラーが発生している
2つ目の呼び出しで「位置引数がキーワード引数の後にある」というエラーが発生している

 2つ目の呼び出しがエラーとなっている。このときに表示されているメッセージには「位置引数がキーワード引数の後にある」と書いてあるのが分かる。位置引数とキーワード引数の両者を関数に渡すときには、順番に注意するようにしよう。

引数のアンパック(展開)

 位置引数とキーワード引数はどちらも反復可能オブジェクトの要素をアンパック(展開)して渡せる。本連載でも何度か触れてきたが、反復可能オブジェクトとは「その要素を1つずつ取り出せるオブジェクト」のことだ。文字列リスト辞書などが代表的な反復可能オブジェクトである。

 まず位置引数に文字列の要素をアンパックして渡してみよう。アンパックするには反復可能オブジェクトの前に「*」を付ける。

print(myfunc(*'abc'))
print(myfunc(1, *'23'))
print(myfunc(*'12', 3))

文字列をアンパックしてmyfunc関数に渡す

 最初の呼び出しでは、文字列が3つの要素にアンパックされたものが位置引数として各パラメーターに渡される。2つ目の呼び出しでは、最初にある整数値の「1」が第1パラメーターに位置引数として渡され、次の文字列'23'をアンパックした結果である文字列'2'と'3'が残りのパラメーターに位置引数として渡される。3つ目の呼び出しでは、最初にある文字列'12'をアンパックした結果である文字列'1'と'2'が最初の2つのパラメーターに位置引数として渡され、整数値の「3」が第3パラメーターに位置引数として渡される。実行結果は次の通り。

文字列をアンパックしてmyfunc関数に渡した結果
文字列をアンパックしてmyfunc関数に渡した結果

 このとき、「通常の位置引数と反復可能オブジェクトをアンパックして得られる要素の総数」が、関数のパラメーターの数と一致している必要がある。試しに、パラメーターの数より多くなるような呼び出しを行ってみよう。以下では、4文字の文字列をアンパックしてmyfunc関数に渡している。

print(myfunc(*'abcd'))

myfunc関数のパラメーターの数よりも多くなるように文字列をアンパック

 これを実行すると次のようになる。

「位置引数は3つだけど、引数が4つあるよ」と怒られた
「位置引数は3つだけど、引数が4つあるよ」と怒られた

 このようにエラーとなった。メッセージには「位置引数は3つだけど、引数が4つあるよ」とあることからも分かるが、反復可能オブジェクトをアンパックして関数に渡すときにはアンパック後の引数の総数とパラメーターの数が一致するように注意しよう(ただし、任意の数の引数をパラメーターに受け取れる関数もある。後述)。

 一方、キーワード引数は単純に文字列をアンパックするだけでは渡せない。「パラメーター名=実引数の値」という形式にするには、辞書などを使用する必要がある。辞書については第7回の「辞書を引数としてformatメソッドを呼び出す」で少し触れた。詳細については第20回「辞書」を参照されたい。簡単にまとめると、辞書とは「キーと値」の対を一括して管理するもので次のように記述する。

some_dict = {'key1': 1, 'key2': '2'}

辞書の定義例

 キーと値の組は「キー: 値」のようにして記述し、複数の組が辞書に含まれる場合は、それらをカンマで区切って、波かっこ「{}」の中に並べる。辞書も反復可能オブジェクトの1つだ。ここでは、次のような辞書を作ってみよう。

arg_dict = {'param3': 'param3', 'param2': 2, 'param1': 1.0}

「paramX: その値」というキーと値の対を3つ含んだ辞書オブジェクト

 これらの辞書に格納されている「キーと値」の組では、キーにmyfunc関数のパラメーターリストにあるパラメーター名が使われていることに注目しよう。そして、この辞書をアンパックしてmyfunc関数に渡すには、辞書の前に「**」を付ければよい。

print(myfunc(**arg_dict))

辞書をアンパックしてmyfunc関数に渡す

 実行すると、以下のようになる。

辞書に含まれている「キー」がキーワード引数のパラメーター名として、値がそれに対応する実引数として渡された
辞書に含まれている「キー」がキーワード引数のパラメーター名として、値がそれに対応する実引数として渡された

 ご覧の通り、辞書をアンパックした場合には、その辞書に含まれているキーがパラメーター名として、キーに対応する値が実引数値として渡される。

 引数のアンパックにはさらに細かな規則もあるが、それらも含めて関数への引数渡しの詳細については公式サイトのドキュメント「呼び出し」を参照されたい。

Copyright© Digital Advantage Corp. All Rights Reserved.

       | 次のページへ
[an error occurred while processing this directive]
ページトップに戻る