こんにちは、吉政創成 菱沼です。
今回もPythonエンジニア育成推進協会のPython 3 エンジニア認定実践試験の主教材「Python実践レシピ/技術評論社」を使って学習中です。
関数にデータを受け渡すのに利用される引数の中で、前回は可変長位置引数と可変長キーワード引数について学びました。今回はキーワード専用引数と、位置専用引数について学びます。
キーワード専用引数とは何か
※Pythonでは関数定義時に使う引数を仮引数(parameter)とし、関数呼び出し時に渡す引数を実引数(argument)と呼ぶそうです。書籍もそれに合わせて記述されています。
関数呼び出し時に、「仮引数名=値」の形で値を渡す方法をキーワード引数というものがありましたが、今回のキーワード専用引数というのは、キーワード引数として指定しなければ呼び出せないという制限を付けたいときに使用されるものだそうです。「*」を付けた後に定義された引数はすべてキーワード専用引数となります。ただ「*」自体は値を受け取っておらず、あくまで「ここから後ろはキーワード専用引数だよ」という線引きになります。
どういった場面で使うのか。これについて、書籍では次のように書かれています。
————–
P.57
bool値などを引数として渡す場合、呼び出し側でキーワードの指定がないと、何に対してTrue(もしくはFalse)なのかがわかりづらくなります。キーワード引数で明示した方が可読性を高めることができるため、キーワードを強要したい際などに使います。
————–
読む側の立場で見たときに、True/Falseだけが突然引数として渡されると確かに、一体何をTrue/Falseするの?と疑問がわきますね。
ちなみに【bool値「など」】と書いてある通り、キーワード専用引数はTrue/False専用ではなく、それ以外の引数での用途としても使用が可能です。例えば、文字のエンコーディングをutf-8に指定したい場合、「utf-8」だけを渡すと、「何の設定にutf-8を適用する?」と考えることになります。なので、「encoding="utf-8"」としてあげることで、その値が何の役割なのかがわかりやすくなります。
ではここで書籍のサンプルコードを確認してみます。
P.57
def sample_func(param1, *, keyword1):
print(f'{param1}, {keyword1}')
sample_func(1, keyword1=False)
1, False
sample_func(1, False)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
sample_func(1, False)
TypeError: sample_func() takes 1 positional argument but 2 were given
2つ目の仮引数の位置に「*」がついたので、3つ目の引数はキーワード専用引数として定義されました。
1つ目の実行ではキーワード付きで値を渡しているのでエラーにはなりませんでしたが、2つ目の実行ではキーワードがついておらず、Falseが位置引数として扱われてしまったため、エラーになっています。
位置専用引数とは?
では次に位置専用引数です。
キーワード専用引数が「キーワード引数でしか渡せない引数」だったのに対し、位置専用引数は「位置引数でしか渡せない引数」です。
キーワード専用引数は「*」が使われましたが、位置専用引数は「/」が使われます。ただ、キーワード専用引数は「*」以降でしたが、位置専用引数は「/」より前のものが対象となります。(「/」も値を受け取るものではありません。)
ではここで書籍のサンプルコードを確認してみます。
P.57
def add(x, y, /):
return x + y
add(1, 2)
3
add(x=1, y=2)
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
add(x=1, y=2)
TypeError: add() got some positional-only arguments passed as keyword arguments: 'x, y'
xとyは位置引数として渡さなければならないという定義がされました。
1つ目の実行では、位置引数として値を渡しているため、問題なく結果が表示されましたが、2つ目の実行では、キーワード引数として値を渡しているため、エラーが出ていることが確認できます。
キーワード専用引数と位置専用引数の両方を使ってみる。
せっかくなので位置専用引数とキーワード専用引数の両方を使ってみたいと思います。

問題なく表示されました。
それではきりが良いので今回はこちらで終了です。
お付き合いいただきありがとうございました。
実践試験について知りたい方は以下をご覧ください。
●Python3エンジニア認定実践試験
