【Python】可変長引数(*args, **kwargs)の使い方
今日は Python プログラミングの「可変長引数」についてご紹介します。
🌟 可変長引数とは?
みなさんは友達とピクニックに行くとき、「何人来るかな?」と考えることがありますよね。
3人かもしれないし、10人かもしれない...。
Python の関数も同じように、「引数がいくつ来るかな?」と考えることがあります。
そんなとき、可変長引数が大活躍!
可変長引数とは、関数に渡す引数の数が変わっても大丈夫な仕組みです。
まるでドラえもんの四次元ポケットのようなものですね!
🍎 *args の使い方
まずは *args から見ていきましょう。この不思議な星印(*)がポイントです!
def fruit_mix(*args):
    print(f"今日のフルーツサラダには {len(args)} 種類の果物が入っています:")
    for fruit in args:
        print(f"- {fruit}")
# 3つの引数で呼び出し
fruit_mix("りんご", "バナナ", "いちご")
# 5つの引数で呼び出し
fruit_mix("りんご", "バナナ", "いちご", "キウイ", "みかん")
このコードを実行すると、引数の数が違っても関数はちゃんと動きます。
すごいですね!
*args は実はタプル(変更できないリスト)として関数内で扱われます。名前は *args じゃなくても大丈夫です。
例えば *fruits でもOKです。
ただ、慣習として多くのプログラマーは *args を使います。
🔑 **kwargs の使い方
次に **kwargs を見てみましょう。
ちなみにkwargs とは「keyword arguments(キーワード引数)」の略。
Python において、キーワード引数とは「名前=値」の形式で関数に渡される引数のことを指します。
例えば、function(name="田中", age=25) のように使うとき、name="田中" と age=25 がキーワード引数。
これらの引数は名前(キーワード)と値のペアになっているため、keyword arguments と呼ばれています。
そして **kwargs という書き方をすると、任意の数のキーワード引数をまとめて受け取ることができるようになります。
この名前は慣習的なもので、**keywords や **params など別の名前を使うこともできますが、多くのPythonプログラマーは **kwargs という名前を使う傾向があります。
*argsと比べて、こちらは二つの星印(**)がポイントです!
def student_info(**kwargs):
    print("生徒カード:")
    for key, value in kwargs.items():
        print(f"{key}: {value}")
# キーワード引数で呼び出し
student_info(名前="たなか", 年齢=14, 好きな教科="数学")
# 別の生徒情報
student_info(名前="すずき", 年齢=13, 好きな教科="国語", 部活="バスケ")
**kwargs はタプルではなく、辞書(dictionary) として関数内で扱われます。
これは、キーワード引数が名前(キー)と値のペアで構成されているためです。
例えば、以下のコードで確認できます:
def check_type(**kwargs):
    print(type(kwargs))
    print(kwargs)
check_type(name="太郎", age=25, city="東京")
このコードを実行すると、次のような出力が得られます:
<class 'dict'>
{'name': '太郎', 'age': 25, 'city': '東京'}
このように、**kwargs は辞書型(dict)として扱われ、キーワード引数の名前がキーになり、その値が辞書の値になります。
そのため、関数内では kwargs.items()、kwargs.keys()、kwargs.values() など、辞書のメソッドを使って処理することができます。
*argsと同様、こちらも名前は自由ですが、慣習として **kwargs がよく使われます。
🌈 *args と **kwargs を一緒に使おう
両方を組み合わせることもできますよ!
ただし、順番が大切です。
必ず *args が先、**kwargs が後です。
def school_info(school_name, *args, **kwargs):
    print(f"【{school_name}】について")
    
    print("クラス:")
    for class_name in args:
        print(f"- {class_name}")
    
    print("\n学校情報:")
    for key, value in kwargs.items():
        print(f"{key}: {value}")
school_info("中央中学校", "1年A組", "2年B組", "3年C組", 校長="山田先生", 生徒数=450, 創立="1985年")
📊 *args と **kwargs の違い
違いを表にまとめてみました:
| 特徴 | *args | **kwargs | 
|---|---|---|
| 記号 | * (アスタリスク1つ) | ** (アスタリスク2つ) | 
| 形式 | 位置引数 | キーワード引数 | 
| 関数内の型 | タプル | 辞書 | 
| 呼び出し例 | func(1, 2, 3) | func(a=1, b=2) | 
😎 実用的な例
実際のプログラミングでどう使うのか、身近な例で見てみましょう:
def advanced_calculator(*args, **kwargs):
    # デフォルト設定
    operation = kwargs.get("operation", "足し算")
    show_steps = kwargs.get("show_steps", False)
    round_digits = kwargs.get("round_digits", 2)
    
    # 引数がない場合
    if len(args) == 0:
        return "数値が入力されていません"
    
    # 計算処理
    if operation == "足し算":
        if show_steps:
            print(f"計算手順: {' + '.join(str(num) for num in args)}")
        result = sum(args)
    
    elif operation == "掛け算":
        if show_steps:
            print(f"計算手順: {' × '.join(str(num) for num in args)}")
        result = 1
        for num in args:
            result *= num
    
    elif operation == "平均":
        if show_steps:
            print(f"合計: {sum(args)} ÷ 個数: {len(args)}")
        result = sum(args) / len(args)
        result = round(result, round_digits)
    
    else:
        result = "その演算はまだできません"
    
    # 追加情報の表示
    if "label" in kwargs:
        print(f"{kwargs['label']}の結果: {result}")
    
    return result
# いろいろな使い方
print(advanced_calculator(1, 2, 3, 4, 5))  # 足し算(デフォルト)
print(advanced_calculator(2, 3, 4, operation="掛け算", show_steps=True))  # 掛け算、計算手順表示
print(advanced_calculator(72, 85, 96, 64, operation="平均", round_digits=1, label="テストの点数"))  # 平均計算、ラベル付き
🎯 まとめ
可変長引数は、柔軟性の高いプログラムを書くための強力な道具です!
- 
*argsは、複数の位置引数を受け取りたいとき - 
**kwargsは、複数のキーワード引数を受け取りたいとき - 両方を使うと、柔軟な関数が作れます
 
最初は難しく感じるかもしれませんが、何度も使ううちにだんだん慣れてきます。
それでは、楽しいPythonライフを!🐍💻
Discussion