可変長引数 | デフォルト引数と可変長引数 | Python本格超入門

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
ad. 価格範囲を指定して商品を探せます

可変長引数

Pythonの関数を定義する際、基本的にはあらかじめ決まった数の引数を設定します。しかし、開発していると「関数に渡したいデータの数が、その時々によって何個になるか分からない」という場面に遭遇することがあります。

そのようなケースで役立つのが可変長引数(かへんちょうひきすう)です。これを使用すると、引数の数を固定せず、1個でも100個でも、あるいは0個でも柔軟に受け取ることができる関数をスマートに定義できるようになります。

可変長位置引数(*args)

通常の引数(位置引数)を任意の数だけ受け取りたい場合は、引数名の頭にアスタリスクを1つ付けた *args(argumentsの略)を使用します。

頭に * を付けると、渡された複数の引数が自動的に1つのタプル(要素の変更ができないリストのようなデータ型)にパックされて関数内部に引き渡されます。

# 可変長位置引数の定義(渡されたデータを args というタプルにまとめる)
def print_numbers(*args):
    print(f"受け取ったデータの型: {type(args)}")  # <class 'tuple'>
    for number in args:
        print(number)

# 1. 引数を5個渡して呼び出し
print_numbers(1, 2, 3, 4, 5)
# 2. 引数を2個だけ渡して呼び出し
print_numbers(10, 20)

上記のコードの解説は以下の通りです。

  1. print_numbers(1, 2, 3, 4, 5) を実行すると、関数内部では args = (1, 2, 3, 4, 5) というタプルとして処理されます。
  2. タプルを受け取っているため、内部では for 文を使って1つずつ要素を取り出すループ処理がそのまま記述できます。

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

引数名=値 という形式の「キーワード引数」を任意の数だけ受け取りたい場合は、引数名の頭にアスタリスクを2つ付けた **kwargs(keyword argumentsの略)を使用します。

頭に ** を付けると、渡された複数のキーワードと値のペアが、自動的に1つの辞書(dict)にパックされて関数内部に引き渡されます。

# 可変長キーワード引数の定義(kwargs という辞書にまとめる)
def print_info(**kwargs):
    print(f"受け取ったデータの型: {type(kwargs)}")  # <class 'dict'>
    for key, value in kwargs.items():
        print(f"{key}: {value}")

# キーワード引数の数を変えて呼び出し
print_info(name="太郎", age=25, city="東京")

上記のコードの解説は以下の通りです。

  1. print_info(name="太郎", age=25, city="東京") のように呼び出すと、関数内部では kwargs = {"name": "太郎", "age": 25, "city": "東京"} という辞書型に変換されます。
  2. 辞書オブジェクトなので、kwargs.items() を使うことで「キーワード(キー)」と「値」をセットで取り出すループ処理が行えます。

【実践】*args と **kwargs の併用と記述順のルール

通常の引数、*args**kwargs はすべて1つの関数の中で混ぜて使うことができます。これにより、どんなデータが来ても受け止めることができる超汎用的な関数を作ることができます。

ただし、並べる順番には「通常の引数 ➔ *args ➔ **kwargs」という厳格な文法ルールがあり、この順序を破ると SyntaxError になります。

# 正しい並び順の例(通常の引数、可変長位置引数、可変長キーワード引数の順)
def greet_people(greeting, *args, **kwargs):
    # argsはタプル
    for name in args:
        print(f"{greeting}、{name}さん!")
    
    # kwargsは辞書
    for key, value in kwargs.items():
        print(f"【ログ情報】 {key}: {value}")

# 関数の呼び出し例
# "こんにちは" が greeting に入り、"太郎" と "次郎" が args にまとまり、age と city が kwargs にまとまる
greet_people("こんにちは", "太郎", "次郎", age=25, city="東京")

応用:引数の「アンパック(展開)」としての * と **

これまでは「バラバラの引数を1つにまとめる」ための *** を解説してきましたが、逆の使い方もできます。すでに手元にあるリストや辞書を、関数呼び出し時に「バラバラに展開して引数に割り当てる」テクニックです。

def sample_func(a, b, c):
    print(a, b, c)

numbers = [10, 20, 30]
user_data = {"a": "犬", "b": "猫", "c": "鳥"}

# リストの前に * を付けると、要素がバラバラに分解されて a, b, c に割り当てられる
sample_func(*numbers)  # sample_func(10, 20, 30) と同じ意味

# 辞書の前に ** を付けると、キーと値がキーワード引数として分解されて割り当てられる
sample_func(**user_data)  # sample_func(a="犬", b="猫", c="鳥") と同じ意味

実務では、Webフレームワークの内部処理や、別の関数へ引数をそのまま中継(転送)したいシチュエーションなどでこの展開テクニックが非常に多用されます。

可変長引数の特徴まとめ

*args**kwargs の仕様の違い一覧です。

記述法 引数の種類 関数内部でのデータ型 主なメリット・用途
*args 位置引数(値のみ) タプル(tuple) 何個データが渡されるか未定のとき。数値をいくつでも受け取って合計する関数などに便利。
**kwargs キーワード引数(key=value 辞書(dict) オプションの設定項目や、ユーザー属性のデータを動的にまとめて受け取りたいときに便利。

※なお、argskwargs という名前自体は単なる慣習(推奨)であり、文法上は *names**options のように自由な変数名にしても * の個数さえ合っていれば可変長引数として機能します。

まとめ

  • 引数の数を自由にする仕組み:可変長引数を使うことで、引数の個数が動的に変わる柔軟な関数を設計できます。
  • *args はタプル、**kwargs は辞書:アスタリスクの個数によって、関数内部でどのようにパックされてデータが届くのか(型)が明確に異なります。
  • 並び順の文法ルールを徹底する:通常の引数を左側に、*args を真ん中に、**kwargs を必ず一番右端に記述するという並び順の厳守が必要です。

可変長引数とアンパックの仕組みをマスターすると、既存の関数をラップ(拡張)して新しい関数を作ったり、大規模なプログラムのライブラリ間でデータをスムーズに受け渡したりできるようになり、Pythonの表現力が一気にプロレベルへと引き上がります。