Python における関数パラメータ

PythonBeginner
オンラインで実践に進む

はじめに

この実験(Lab)では、Python においてパラメータを持つ関数を定義し、使用する方法を探ります。関数は入力を受け付けることができるようになると、動的で再利用性が高まり、はるかに強力になります。

本稿では、位置引数(positional parameters)、デフォルト値(default values)、キーワード引数(keyword arguments)、可変長引数(variable-length arguments)など、いくつかの種類の関数パラメータについて解説します。実践的な例を通して、さまざまな入力を処理できる柔軟な関数を作成する方法を学びます。

位置引数を持つ関数の定義

パラメータを使用すると、関数にデータを渡すことができ、受け取る入力に基づいてその動作を適応させることが可能になります。最も一般的なタイプである位置引数(positional parameters)から始めましょう。関数に渡される引数は、その順序に基づいてこれらのパラメータに割り当てられます。

まず、WebIDE の左側にあるファイルエクスプローラでファイル positional_params.py を見つけて開いてください。

次に、name という 1 つのパラメータを受け入れる hello という名前の関数を定義します。positional_params.py ファイルに次のコードを追加してください。

def hello(name):
    print(f'Hello, {name}!')

hello('John')
hello('Alice')

このコードでは、nameパラメータであり、関数定義におけるプレースホルダーとして機能します。hello('John') のように関数を呼び出すとき、値 'John'name パラメータに割り当てられる引数(argument)です。

スクリプトを実行するには、上部メニューの Terminal -> New Terminal をクリックして、WebIDE で新しいターミナルを開きます。次に、次のコマンドを実行します。

python3 ~/project/positional_params.py

関数が異なる引数に対して異なる結果を生成したことを示す、次の出力が表示されます。

Hello, John!
Hello, Alice!

関数が位置引数で定義されている場合、呼び出す際には、それぞれの引数に対応する引数を必ず提供する必要があります。これを忘れるとエラーになります。

デフォルト引数の値の使用

パラメータにデフォルト値を提供できると便利です。関数呼び出し時にそのパラメータの引数が提供されない場合、デフォルト値が使用されます。これにより、そのパラメータはオプションになります。

必須の引数なしで関数を呼び出した場合に何が起こるかを見てみましょう。default_params.py ファイルを開き、次のコードを追加してください。

def hello(name):
    print(f'Hello, {name}!')

hello()

ファイルを保存し、ターミナルから実行します。

python3 ~/project/default_params.py

これにより TypeError が発生します。なぜなら、関数 hello は 1 つの引数を期待していましたが、何も受け取らなかったためです。

Traceback (most recent call last):
  File "/home/labex/project/default_params.py", line 4, in <module>
    hello()
TypeError: hello() missing 1 required positional argument: 'name'

これを修正するために、name パラメータにデフォルト値を割り当てることができます。default_params.py ファイルの内容を次のコードに置き換えて修正します。

def hello(name="World"):
    print(f'Hello, {name}!')

hello()
hello("Jobs")

ここで、スクリプトを再度実行します。

python3 ~/project/default_params.py

出力は次のようになります。

Hello, World!
Hello, Jobs!

最初の呼び出しではデフォルト値の "World" が使用され、2 回目の呼び出しでは提供された引数 "Jobs" が使用されています。

重要なルール: 関数定義において、デフォルト値を持たないすべてのパラメータは、デフォルト値を持つ任意のパラメータよりも前に来なければなりません。例えば、def func(a, b="default") は正しいですが、def func(a="default", b)SyntaxError を引き起こします。

キーワードを使用した引数の受け渡し

関数を呼び出す際、引数を提供しているパラメータの名前を明示的に指定できます。これらはキーワード引数(keyword arguments)と呼ばれます。主な利点は、順序を気にする必要がなくなり、コードの可読性が向上することです。

keyword_args.py ファイルを開き、次のコードを追加してください。

def person(name, age):
    print(f"{name} is {age} years old.")

## キーワード引数を使用して呼び出す - 順序は関係ない
person(name="Zhang San", age=25)
person(age=50, name="Li Si")

ファイルを保存し、ターミナルから実行します。

python3 ~/project/keyword_args.py

引数の順序に関係なく、両方の呼び出しが正しく機能していることがわかります。

Zhang San is 25 years old.
Li Si is 50 years old.

単一の関数呼び出しで、位置引数とキーワード引数を混在させることもできます。ただし、1 つのルールに従う必要があります。すべて位置引数は、任意のキーワード引数よりも前に来なければなりません。

このルールが機能することを確認するために、keyword_args.py の内容を以下に置き換えてください。

def person(name, age):
    print(f"{name} is {age} years old.")

## これは位置引数とキーワード引数の有効な組み合わせです
person("Wang Wu", age=26)

## これは SyntaxError を引き起こします:positional argument follows keyword argument
## person(age=28, "Zhao Liu")

スクリプトを再度実行します。有効な呼び出しは期待どおりに実行されます。

python3 ~/project/keyword_args.py

期待される出力:

Wang Wu is 26 years old.

可変個数の引数を処理する

Python の関数は、可変長の引数を受け付けるように設計できます。これは、関数にいくつの引数が渡されるかを事前に知ることができない場合に役立ちます。

可変長の位置引数 (*args)

パラメータ名の前にアスタリスク * を付けることで、任意の数の位置引数をタプルにまとめることができます。args という名前は慣習ですが、有効な任意のパラメータ名を使用できます。

可変長のキーワード引数 (**kwargs)

パラメータ名の前に二重アスタリスク ** を付けることで、任意の数のキーワード引数を辞書(dictionary)にまとめることができます。kwargs という名前も慣習です。

これらの概念を組み合わせてみましょう。variable_args.py ファイルを開き、次のコードを追加します。

## *args を使用して可変数の数値を合計する
def calculate_sum(*numbers):
    print(f"Arguments received as a tuple: {numbers}")
    total = sum(numbers)
    print(f"Sum: {total}\n")

## **kwargs を使用して追加のプロフィール情報をキャプチャする
def person_profile(name, age, **other_info):
    print(f"Name: {name}")
    print(f"Age: {age}")
    print(f"Other Info: {other_info}\n")

## 関数の呼び出し
calculate_sum(1, 2, 3)
calculate_sum(10, 20, 30, 40, 50)

person_profile('Wang Wu', 26, gender="Male", job="Writer")
person_profile('Zhao Liu', 28, city="Beijing", status="Active")

ターミナルからスクリプトを実行します。

python3 ~/project/variable_args.py

出力は、numbers がタプルであり、other_info が辞書であることを示しています。

Arguments received as a tuple: (1, 2, 3)
Sum: 6

Arguments received as a tuple: (10, 20, 30, 40, 50)
Sum: 150

Name: Wang Wu
Age: 26
Other Info: {'gender': 'Male', 'job': 'Writer'}

Name: Zhao Liu
Age: 28
Other Info: {'city': 'Beijing', 'status': 'Active'}

特殊なパラメータ型を探る

Python では、関数に引数がどのように渡されるかを強制する機能があり、関数のシグネチャ(定義)をより明確で曖昧さのないものにすることができます。パラメータを位置専用(positional-only)またはキーワード専用(keyword-only)として指定できます。

位置専用パラメータ (/)

パラメータが位置によってのみ渡されることを指定するには、関数定義内でスラッシュ(/)の前にそれらを配置します。

キーワード専用パラメータ (*)

パラメータがキーワードによってのみ渡されることを指定するには、アスタリスク(*)の後にそれらを配置します。* の後にパラメータ名が続かない場合、それ以降のすべてのパラメータはキーワード専用でなければならないことを意味します。

これらの型を組み合わせる方法を見てみましょう。special_params.py ファイルを開き、次のコードを追加します。この例では、位置専用、標準、キーワード専用のパラメータを持つ関数を定義します。

def school_info(name, /, standard_param, *, city):
    print(f'Positional-Only (name): {name}')
    print(f'Standard (standard_param): {standard_param}')
    print(f'Keyword-Only (city): {city}')
    print('---')

## この関数では:
## - `name` は位置によって渡されなければならない。
## - `standard_param` は位置またはキーワードで渡すことができる。
## - `city` はキーワードで渡されなければならない。

## 有効な呼び出し
school_info("Peking University", "PKU", city="Beijing")
school_info("Tsinghua University", standard_param="THU", city="Beijing")

## 無効な呼び出しの例(エラーを防ぐためコメントアウト)
## school_info(name="Zhejiang University", "ZJU", city="Hangzhou")  ## TypeError: name is positional-only
## school_info("Fudan University", "FDU", "Shanghai")               ## TypeError: city is keyword-only

スクリプトを実行して、有効な呼び出しの結果を確認します。

python3 ~/project/special_params.py

出力は次のようになります。

Positional-Only (name): Peking University
Standard (standard_param): PKU
Keyword-Only (city): Beijing
---
Positional-Only (name): Tsinghua University
Standard (standard_param): THU
Keyword-Only (city): Beijing
---

この構文は、堅牢で自己文書化された関数を作成するのに役立ち、関数の呼び出し方法の曖昧さを減らします。

まとめ

この実験(Lab)では、Python 関数におけるパラメータの使用の基本を学びました。位置引数(positional parameters)を定義および呼び出す方法、デフォルト値を提供してパラメータをオプションにする方法、そしてより読みやすいコードのためにキーワード引数(keyword arguments)を使用する方法を網羅しました。さらに、可変長の引数(*args および **kwargs)を受け入れる柔軟な関数を作成する方法を探りました。最後に、引数の渡し方を強制するための特殊な構文(/ および *)を確認し、これにより関数の明確さと堅牢性が向上します。