ステップ17:関数の応用

⚙️ ステップ17: 関数の応用

デフォルト引数、キーワード引数、スコープをマスターしよう!

前のステップでは関数の基本(def、引数、return)を学びました。このステップでは、関数をもっと便利に使うための応用テクニックを学びます。

📖 このステップで学ぶこと

・デフォルト引数(引数を省略できるようにする)

・キーワード引数(引数を名前で指定する)

・可変長引数(*args、**kwargs)

・スコープ(変数の有効範囲)

🎯 1. デフォルト引数

デフォルト引数を使うと、引数が渡されなかった時の「初期値」を設定できます。

🔰 デフォルト引数とは?

例えば、挨拶する関数を考えてみましょう。

普通の関数だと、毎回挨拶の言葉を指定する必要があります。

コード:デフォルト引数なしの場合

※スマートフォンでは横スクロールできます

# 毎回greetingを指定する必要がある
def greet(name, greeting):
    print(f"{greeting}、{name}さん!")

greet("太郎", "こんにちは")
greet("花子", "こんにちは")  # また「こんにちは」を書く
greet("次郎", "こんにちは")  # また「こんにちは」を書く

「こんにちは」を毎回書くのは面倒ですね。デフォルト引数を使えば、省略できます。

📘 デフォルト引数の書き方

📝 デフォルト引数の構文

def 関数名(引数1, 引数2=デフォルト値):

・引数名の後に=デフォルト値を書く

・引数が渡されなかった時、デフォルト値が使われる

・デフォルト引数は省略できる

完成コード:デフォルト引数ありの場合

※スマートフォンでは横スクロールできます

# greeting="こんにちは" → デフォルト値を設定
def greet(name, greeting="こんにちは"):
    print(f"{greeting}、{name}さん!")

# 2つの引数を渡す場合
greet("太郎", "おはよう")  # greetingに"おはよう"が入る

# greetingを省略する場合(デフォルト値が使われる)
greet("花子")  # greetingは"こんにちは"になる
greet("次郎")  # greetingは"こんにちは"になる

実行結果

おはよう、太郎さん!
こんにちは、花子さん!
こんにちは、次郎さん!

💡 デフォルト引数のメリット

・よく使う値を毎回書かなくていい

・必要な時だけ値を変更できる

・関数の呼び出しがシンプルになる

📝 複数のデフォルト引数

デフォルト引数は複数設定できます。

完成コード:複数のデフォルト引数

※スマートフォンでは横スクロールできます

# name: 必須の引数
# age=0: デフォルト値は0
# hobby="なし": デフォルト値は"なし"
def introduce(name, age=0, hobby="なし"):
    print(f"名前: {name}")
    print(f"年齢: {age}歳")
    print(f"趣味: {hobby}")
    print("---")

# 全ての引数を指定
introduce("太郎", 15, "サッカー")

# hobbyを省略(デフォルト値"なし"が使われる)
introduce("花子", 14)

# ageとhobbyを省略(両方デフォルト値が使われる)
introduce("次郎")

実行結果

名前: 太郎
年齢: 15歳
趣味: サッカー
---
名前: 花子
年齢: 14歳
趣味: なし
---
名前: 次郎
年齢: 0歳
趣味: なし
---

📝 デフォルト引数の順番ルール

🔑 重要!デフォルト引数の位置

デフォルト引数は、必ず普通の引数の後ろに書きます。

✅ 正しい:def func(a, b, c=10):

✅ 正しい:def func(a, b=5, c=10):

❌ エラー:def func(a=5, b, c): → デフォルト引数が前にある

コード:エラーになる例

※スマートフォンでは横スクロールできます

# ❌ エラーになる例
# デフォルト引数が普通の引数より前にある
def bad_func(a=1, b):  # SyntaxError!
    print(a, b)

エラーメッセージ

SyntaxError: non-default argument follows default argument

「デフォルト引数の後に、普通の引数があります」というエラーです。

📝 実践例:メール送信関数

実際のプログラムでよく使うパターンを見てみましょう。

完成コード:メール送信関数

※スマートフォンでは横スクロールできます

# to, subject, body: 必須の引数
# from_email: デフォルト値あり(送信元をよく同じにする場合に便利)
def send_email(to, subject, body, from_email="noreply@example.com"):
    print(f"送信元: {from_email}")
    print(f"宛先: {to}")
    print(f"件名: {subject}")
    print(f"本文: {body}")
    print("メール送信完了!")
    print("---")

# 送信元を指定する場合
send_email("user@example.com", "お知らせ", "こんにちは", "admin@example.com")

# 送信元を省略する場合(デフォルト値が使われる)
send_email("user@example.com", "お知らせ", "こんにちは")

実行結果

送信元: admin@example.com
宛先: user@example.com
件名: お知らせ
本文: こんにちは
メール送信完了!
---
送信元: noreply@example.com
宛先: user@example.com
件名: お知らせ
本文: こんにちは
メール送信完了!
---

📌 デフォルト引数のまとめ

・引数に=デフォルト値を付けると、省略可能になる

・デフォルト引数は普通の引数の後ろに書く

・よく使う値をデフォルトにすると便利

・必要な時だけ別の値を渡せる

🏷️ 2. キーワード引数

キーワード引数を使うと、引数の名前を指定して値を渡せます。順番を気にしなくていいので、分かりやすくなります!

🔰 キーワード引数とは?

今までの引数の渡し方は「位置引数」と呼ばれます。順番で引数が決まります。

コード:位置引数(従来の方法)

※スマートフォンでは横スクロールできます

def introduce(name, age, hobby):
    print(f"{name}さん、{age}歳、趣味は{hobby}")

# 順番通りに渡す(位置引数)
introduce("太郎", 15, "サッカー")  # name=太郎, age=15, hobby=サッカー

キーワード引数を使うと、引数の名前を指定して渡せます。

コード:キーワード引数

※スマートフォンでは横スクロールできます

def introduce(name, age, hobby):
    print(f"{name}さん、{age}歳、趣味は{hobby}")

# キーワード引数で渡す(引数名=値 の形式)
introduce(name="花子", age=14, hobby="読書")

# 順番を変えてもOK!
introduce(hobby="音楽", name="次郎", age=16)

実行結果

花子さん、14歳、趣味は読書
次郎さん、16歳、趣味は音楽

💡 キーワード引数のメリット

・引数の順番を覚えなくていい

・コードを読んだ時に、何の値か一目で分かる

・間違った順番で渡すミスを防げる

📘 キーワード引数の書き方

📝 キーワード引数の構文

関数を呼び出す時に:関数名(引数名1=値1, 引数名2=値2)

・引数名と値を=で結ぶ

・順番は自由

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

位置引数とキーワード引数は、一緒に使えます。ただし、ルールがあります。

完成コード:位置引数とキーワード引数の混在

※スマートフォンでは横スクロールできます

def calculate(a, b, operation="+"):
    if operation == "+":
        return a + b
    elif operation == "-":
        return a - b
    elif operation == "*":
        return a * b

# 最初の2つは位置引数、最後はキーワード引数
result1 = calculate(10, 5, operation="*")
print(f"10 * 5 = {result1}")

# キーワード引数でoperationを指定
result2 = calculate(10, 5, operation="-")
print(f"10 - 5 = {result2}")

# operationを省略(デフォルト値"+"が使われる)
result3 = calculate(10, 5)
print(f"10 + 5 = {result3}")

実行結果

10 * 5 = 50
10 - 5 = 5
10 + 5 = 15

📝 順番のルール

🔑 重要!位置引数とキーワード引数の順番

位置引数は、キーワード引数のに書く必要があります。

✅ 正しい:func(1, 2, key=3)

✅ 正しい:func(1, key1=2, key2=3)

❌ エラー:func(key=3, 1, 2) → キーワード引数が位置引数より前

📝 キーワード引数で読みやすいコード

引数が多い関数では、キーワード引数を使うと非常に読みやすくなります。

コード:読みやすさの比較

※スマートフォンでは横スクロールできます

def create_user(name, age, email, city, job):
    print(f"ユーザー作成: {name}, {age}歳, {email}, {city}, {job}")

# 位置引数だけ → 何の値か分かりにくい
create_user("太郎", 25, "taro@example.com", "東京", "エンジニア")

# キーワード引数を使う → 何の値か一目で分かる
create_user(
    name="花子",
    age=24,
    email="hanako@example.com",
    city="大阪",
    job="デザイナー"
)

実行結果

ユーザー作成: 太郎, 25歳, taro@example.com, 東京, エンジニア
ユーザー作成: 花子, 24歳, hanako@example.com, 大阪, デザイナー

📌 位置引数とキーワード引数の比較

比較項目 位置引数 キーワード引数
書き方 func(1, 2, 3) func(a=1, b=2, c=3)
順番 定義と同じ順番が必要 自由
読みやすさ 引数が少ない時は良い 引数が多い時に良い

📝 デフォルト引数とキーワード引数の組み合わせ

デフォルト引数とキーワード引数を組み合わせると、非常に柔軟な関数が作れます。

完成コード:サーバー設定関数

※スマートフォンでは横スクロールできます

# 全ての引数にデフォルト値を設定
def setup_server(host="localhost", port=8000, debug=False):
    print(f"サーバー設定:")
    print(f"  ホスト: {host}")
    print(f"  ポート: {port}")
    print(f"  デバッグ: {debug}")
    print("---")

# デフォルト設定(引数なし)
setup_server()

# 一部だけ変更(キーワード引数で指定)
setup_server(port=3000)

# 複数変更
setup_server(host="example.com", debug=True)

実行結果

サーバー設定:
  ホスト: localhost
  ポート: 8000
  デバッグ: False
---
サーバー設定:
  ホスト: localhost
  ポート: 3000
  デバッグ: False
---
サーバー設定:
  ホスト: example.com
  ポート: 8000
  デバッグ: True
---

💡 このパターンの便利さ

全ての引数にデフォルト値を設定しておくと:

・何も指定しなければデフォルト設定が使われる

・変更したい項目だけをキーワード引数で指定できる

・設定ファイルのような使い方ができる

📦 3. 可変長引数 (*args)

*argsを使うと、引数の個数が決まっていない関数を作れます。「いくつでも引数を受け取れる」関数です。

🔰 可変長引数とは?

例えば、複数の数を足し合わせる関数を考えてみましょう。

普通の関数だと、引数の数を決めなければなりません。

コード:引数の数が固定の場合

※スマートフォンでは横スクロールできます

# 2つの数しか足せない
def add_two(a, b):
    return a + b

# 3つの数しか足せない
def add_three(a, b, c):
    return a + b + c

# 数が増えるたびに関数を作る? → 大変!

*argsを使えば、いくつでも引数を受け取れます!

📘 *argsの書き方

📝 *argsの構文

def 関数名(*args):

・引数名の前に*(アスタリスク)を付ける

・渡された全ての引数がタプルとして受け取られる

argsという名前は慣例(別の名前でもOK)

完成コード:いくつでも足せる関数

※スマートフォンでは横スクロールできます

# *numbers で、渡された全ての引数をタプルとして受け取る
def sum_all(*numbers):
    print(f"受け取った引数: {numbers}")  # タプルとして表示
    print(f"引数の型: {type(numbers)}")
    
    # タプルの合計を計算
    total = 0
    for num in numbers:
        total += num
    return total

# いくつでも引数を渡せる!
print(sum_all(1, 2, 3))
print("---")
print(sum_all(10, 20, 30, 40, 50))
print("---")
print(sum_all(5))

実行結果

受け取った引数: (1, 2, 3)
引数の型: <class 'tuple'>
6
---
受け取った引数: (10, 20, 30, 40, 50)
引数の型: <class 'tuple'>
150
---
受け取った引数: (5,)
引数の型: <class 'tuple'>
5

💡 ポイント

*numbersは、渡された引数をタプルにまとめます

・タプルなので、for文で繰り返し処理できます

・引数が1つでも、タプルになります(5,)

📝 普通の引数と*argsの組み合わせ

普通の引数と*argsは一緒に使えます。

完成コード:普通の引数 + *args

※スマートフォンでは横スクロールできます

# greeting: 普通の引数
# *names: 可変長引数(複数の名前を受け取る)
def create_message(greeting, *names):
    message = greeting + "、"
    for name in names:
        message += name + "さん、"
    return message

# greetingの後に、いくつでも名前を渡せる
print(create_message("こんにちは", "太郎", "花子", "次郎"))
print(create_message("おはよう", "田中"))

実行結果

こんにちは、太郎さん、花子さん、次郎さん、
おはよう、田中さん、

📝 実践例:最大値を求める関数

完成コード:いくつでも比較できる最大値関数

※スマートフォンでは横スクロールできます

def find_max(*numbers):
    # 引数が0個の場合
    if len(numbers) == 0:
        return None
    
    # 最初の数を最大値と仮定
    max_num = numbers[0]
    
    # 全ての数と比較
    for num in numbers:
        if num > max_num:
            max_num = num
    
    return max_num

print(f"最大値: {find_max(5, 2, 9, 1, 7)}")
print(f"最大値: {find_max(10, 30, 20)}")
print(f"最大値: {find_max(100)}")

実行結果

最大値: 9
最大値: 30
最大値: 100

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

**kwargsを使うと、名前付きの引数をいくつでも受け取れます。

🔰 **kwargsとは?

*argsは位置引数を受け取りましたが、**kwargsはキーワード引数を受け取ります。

📘 **kwargsの書き方

📝 **kwargsの構文

def 関数名(**kwargs):

・引数名の前に**(アスタリスク2つ)を付ける

・渡された全てのキーワード引数が辞書として受け取られる

kwargsという名前は慣例(別の名前でもOK)

完成コード:**kwargsの基本

※スマートフォンでは横スクロールできます

# **info で、渡された全てのキーワード引数を辞書として受け取る
def print_info(**info):
    print(f"受け取った引数: {info}")
    print(f"引数の型: {type(info)}")
    
    # 辞書なので、items()で繰り返し処理
    for key, value in info.items():
        print(f"  {key}: {value}")

# キーワード引数をいくつでも渡せる!
print_info(name="太郎", age=15, hobby="サッカー")
print("---")
print_info(city="東京", weather="晴れ")

実行結果

受け取った引数: {'name': '太郎', 'age': 15, 'hobby': 'サッカー'}
引数の型: <class 'dict'>
  name: 太郎
  age: 15
  hobby: サッカー
---
受け取った引数: {'city': '東京', 'weather': '晴れ'}
引数の型: <class 'dict'>
  city: 東京
  weather: 晴れ

📝 普通の引数と**kwargsの組み合わせ

完成コード:プロフィール作成関数

※スマートフォンでは横スクロールできます

# name: 必須の引数
# **details: 任意のキーワード引数(何でも追加できる)
def create_profile(name, **details):
    print(f"=== {name}さんのプロフィール ===")
    
    # 追加情報があれば表示
    if details:
        for key, value in details.items():
            print(f"{key}: {value}")
    else:
        print("(追加情報なし)")

# 名前だけ
create_profile("太郎")
print()

# 名前 + 追加情報いろいろ
create_profile("花子", age=14, city="東京", hobby="読書", school="〇〇中学校")

実行結果

=== 太郎さんのプロフィール ===
(追加情報なし)

=== 花子さんのプロフィール ===
age: 14
city: 東京
hobby: 読書
school: 〇〇中学校

📝 *argsと**kwargsを両方使う

*args**kwargsは一緒に使えます。順番に注意しましょう。

📌 引数の順番ルール

def func(普通の引数, *args, **kwargs):

1. 普通の引数(必須)

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

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

この順番を守る必要があります。

完成コード:全部入り関数

※スマートフォンでは横スクロールできます

# required: 必須の引数
# *args: 可変長の位置引数
# **kwargs: 可変長のキーワード引数
def super_function(required, *args, **kwargs):
    print(f"必須引数: {required}")
    print(f"追加の位置引数: {args}")
    print(f"キーワード引数: {kwargs}")

# 全ての種類の引数を渡す
super_function(
    "必須の値",           # required
    1, 2, 3,              # *args
    key1="値1", key2="値2"  # **kwargs
)

実行結果

必須引数: 必須の値
追加の位置引数: (1, 2, 3)
キーワード引数: {'key1': '値1', 'key2': '値2'}

📌 *argsと**kwargsのまとめ

比較項目 *args **kwargs
記号 *(アスタリスク1つ) **(アスタリスク2つ)
受け取る型 タプル 辞書
呼び出し方 func(1, 2, 3) func(a=1, b=2)
用途 位置引数をいくつでも キーワード引数をいくつでも

🔍 5. スコープ – 変数の有効範囲

スコープとは、変数が使える範囲のことです。関数の中と外では、変数の扱いが違います。

🔰 スコープとは?

変数には「使える範囲」があります。関数の中で作った変数は、関数の外では使えません。

📌 2種類の変数

種類 定義場所 使える範囲
ローカル変数 関数の中 その関数の中だけ
グローバル変数 関数の外 どこからでも参照可能

📝 ローカル変数

関数の中で定義した変数は、その関数の中でしか使えません。これをローカル変数といいます。

完成コード:ローカル変数の例

※スマートフォンでは横スクロールできます

def my_function():
    # x は関数の中で定義 → ローカル変数
    x = 10
    print(f"関数の中: x = {x}")

# 関数を呼び出す
my_function()

# 関数の外でxを使おうとすると...
# print(x)  # ❌ エラー! xは関数の外では使えない

実行結果

関数の中: x = 10

コメントを外してprint(x)を実行すると、エラーになります。

コード:エラーになる例

※スマートフォンでは横スクロールできます

def my_function():
    x = 10

my_function()
print(x)  # ❌ エラー!

エラーメッセージ

NameError: name 'x' is not defined

「xは定義されていません」というエラーです。

関数の中のxは、関数の外からは見えません。

📝 グローバル変数

関数の外で定義した変数は、どこからでも参照できます。これをグローバル変数といいます。

完成コード:グローバル変数の参照

※スマートフォンでは横スクロールできます

# 関数の外で定義 → グローバル変数
x = 100

def my_function():
    # 関数の中からグローバル変数を参照できる
    print(f"関数の中から参照: x = {x}")

my_function()
print(f"関数の外から参照: x = {x}")

実行結果

関数の中から参照: x = 100
関数の外から参照: x = 100

📝 同じ名前の変数がある場合

グローバル変数とローカル変数が同じ名前の場合、どうなるでしょうか?

完成コード:同じ名前の変数

※スマートフォンでは横スクロールできます

# グローバル変数 x = 100
x = 100

def my_function():
    # ローカル変数 x = 10(同じ名前だが別物)
    x = 10
    print(f"関数の中: x = {x}")  # ローカル変数のxが使われる

my_function()
print(f"関数の外: x = {x}")  # グローバル変数のxは変わっていない

実行結果

関数の中: x = 10
関数の外: x = 100

💡 重要なポイント

・関数の中では、ローカル変数が優先される

・関数の中でx = 10と書くと、新しいローカル変数が作られる

・グローバル変数のxは変更されない(別々の変数)

📝 globalキーワード

関数の中でグローバル変数を変更したい時は、globalキーワードを使います。

完成コード:globalキーワード

※スマートフォンでは横スクロールできます

# グローバル変数
count = 0

def increment():
    # global count → 「このcountはグローバル変数のことです」と宣言
    global count
    count += 1  # グローバル変数を変更
    print(f"カウント: {count}")

# 関数を3回呼び出す
increment()
increment()
increment()

print(f"最終カウント: {count}")

実行結果

カウント: 1
カウント: 2
カウント: 3
最終カウント: 3

⚠️ globalの使用は最小限に

globalは便利ですが、使いすぎるとコードが分かりにくくなります。

以下の理由から、できるだけ避けるのがおすすめです:

・どこで変数が変更されるか分かりにくい

・バグが起きやすい

・テストしにくい

代わりに、引数と戻り値を使いましょう。

📝 globalを使わない方法(推奨)

引数と戻り値を使えば、globalを使わずに同じことができます。

完成コード:引数と戻り値を使う方法

※スマートフォンでは横スクロールできます

# カウンターを引数で受け取り、戻り値で返す
def increment(count):
    count += 1
    return count

# 変数を関数に渡して、戻り値で更新
count = 0
count = increment(count)  # 0 → 1
print(f"カウント: {count}")

count = increment(count)  # 1 → 2
print(f"カウント: {count}")

count = increment(count)  # 2 → 3
print(f"カウント: {count}")

実行結果

カウント: 1
カウント: 2
カウント: 3

💡 ベストプラクティス

・グローバル変数は最小限に

・関数は引数と戻り値でやり取りする

globalはできるだけ使わない

・どうしても必要な時だけ使う(設定値など)

📝 スコープの図解

📌 スコープのイメージ

┌─────────────────────────────────────┐
│  グローバルスコープ(関数の外)      │
│  x = 100  ← グローバル変数          │
│                                     │
│  ┌─────────────────────────────┐   │
│  │  ローカルスコープ(関数の中)│   │
│  │  y = 10  ← ローカル変数     │   │
│  │                             │   │
│  │  print(x)  ← OK(参照可能) │   │
│  │  print(y)  ← OK             │   │
│  └─────────────────────────────┘   │
│                                     │
│  print(x)  ← OK                     │
│  print(y)  ← ❌ エラー(見えない) │
└─────────────────────────────────────┘

📌 スコープのまとめ

ローカル変数:関数の中でしか使えない

グローバル変数:どこからでも参照可能

・同じ名前ならローカル変数が優先される

・グローバル変数を変更するにはglobalが必要

・でもglobalは最小限に!引数と戻り値を使おう

🎯 6. 実践的な例

ここまで学んだテクニックを組み合わせた実用例を見てみましょう。

例1: 柔軟なログ関数

デフォルト引数と**kwargsを組み合わせた、実用的なログ関数を作ってみましょう。

完成コード:ログ関数

※スマートフォンでは横スクロールできます

# message: 必須
# level: デフォルト値あり
# **details: 追加情報(任意)
def log(message, level="INFO", **details):
    print(f"[{level}] {message}")
    
    # 追加情報があれば表示
    if details:
        print("  詳細:")
        for key, value in details.items():
            print(f"    {key}: {value}")

# シンプルなログ
log("プログラム開始")

# レベルを指定
log("処理中...", level="DEBUG")

# 詳細情報付きのエラーログ
log("エラー発生", level="ERROR", error_code=404, file="main.py", line=42)

実行結果

[INFO] プログラム開始
[DEBUG] 処理中...
[ERROR] エラー発生
  詳細:
    error_code: 404
    file: main.py
    line: 42

例2: 設定をマージする関数

デフォルト設定とユーザー設定をマージする関数を作ってみましょう。

完成コード:設定マージ関数

※スマートフォンでは横スクロールできます

def get_config(**user_config):
    # デフォルト設定
    default_config = {
        "host": "localhost",
        "port": 8000,
        "debug": False,
        "timeout": 30
    }
    
    # ユーザー設定でデフォルトを上書き
    # update()メソッドで辞書をマージ
    default_config.update(user_config)
    
    return default_config

# デフォルト設定を取得
config1 = get_config()
print(f"デフォルト: {config1}")

# 一部を変更
config2 = get_config(port=3000, debug=True)
print(f"カスタム: {config2}")

実行結果

デフォルト: {'host': 'localhost', 'port': 8000, 'debug': False, 'timeout': 30}
カスタム: {'host': 'localhost', 'port': 3000, 'debug': True, 'timeout': 30}

例3: HTMLタグ生成関数

タグ名と属性から、HTMLタグを生成する関数を作ってみましょう。

完成コード:HTMLタグ生成関数

※スマートフォンでは横スクロールできます

# tag: タグ名(必須)
# content: タグの中身(必須)
# **attributes: 属性(任意)
def create_tag(tag, content, **attributes):
    # 属性を文字列に変換
    # 例: href="http://..." target="_blank"
    attrs = " ".join([f'{k}="{v}"' for k, v in attributes.items()])
    
    if attrs:
        return f"<{tag} {attrs}>{content}</{tag}>"
    else:
        return f"<{tag}>{content}</{tag}>"

# シンプルなタグ
print(create_tag("p", "こんにちは"))

# 属性付きのタグ
print(create_tag("a", "リンク", href="http://example.com", target="_blank"))

# divタグ
print(create_tag("div", "コンテンツ", id="main", style="color: red"))

実行結果

<p>こんにちは</p>
<a href="http://example.com" target="_blank">リンク</a>
<div id="main" style="color: red">コンテンツ</div>

📝 練習問題(12問)

ここまで学んだことを実際に手を動かして確認しましょう。

問題1:デフォルト引数の挨拶(初級)

📋 問題

名前と挨拶の言葉を引数に取る関数を作りましょう。挨拶のデフォルト値は「こんにちは」とします。

解答を見る

コード

※スマートフォンでは横スクロールできます

# message="こんにちは" でデフォルト値を設定
def greet(name, message="こんにちは"):
    print(f"{message}、{name}さん!")

# デフォルト値を使用
greet("太郎")

# デフォルト値を上書き
greet("花子", "おはよう")

実行結果

こんにちは、太郎さん!
おはよう、花子さん!

問題2:キーワード引数で計算(初級)

📋 問題

幅と高さを引数に取り、面積を返す関数を作り、キーワード引数を使って呼び出しましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

def calc_area(width, height):
    return width * height

# キーワード引数で呼び出し
area = calc_area(width=5, height=10)
print(f"面積: {area}")

実行結果

面積: 50

問題3:任意個数の合計(初級)

📋 問題

*argsを使って、渡された数値の合計を返す関数を作りましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

# *numbers で任意個数の引数を受け取る
def sum_numbers(*numbers):
    return sum(numbers)

print(sum_numbers(1, 2, 3, 4, 5))
print(sum_numbers(10, 20))

実行結果

15
30

問題4:デフォルト値で円の計算(中級)

📋 問題

半径を引数に取り、円の面積を返す関数を作りましょう。円周率πのデフォルト値は3.14とします。

解答を見る

コード

※スマートフォンでは横スクロールできます

# pi=3.14 でデフォルト値を設定
def circle_area(radius, pi=3.14):
    return pi * radius ** 2

# デフォルトのπを使用
print(circle_area(5))

# より精密なπを使用
print(circle_area(5, pi=3.14159))

実行結果

78.5
78.53975

問題5:任意個数の平均(中級)

📋 問題

*argsを使って、渡された数値の平均を返す関数を作りましょう。引数が0個の場合は0を返します。

解答を見る

コード

※スマートフォンでは横スクロールできます

def average(*numbers):
    # 引数が0個の場合
    if len(numbers) == 0:
        return 0
    
    return sum(numbers) / len(numbers)

print(average(10, 20, 30))
print(average(5, 10, 15, 20))

実行結果

20.0
12.5

問題6:辞書を作る関数(中級)

📋 問題

**kwargsを使って、渡されたキーワード引数を辞書として返す関数を作りましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

# **kwargs は辞書として受け取れる
def make_dict(**kwargs):
    return kwargs

result = make_dict(name="太郎", age=15, hobby="サッカー")
print(result)

実行結果

{'name': '太郎', 'age': 15, 'hobby': 'サッカー'}

問題7:ユーザー情報の表示(中級)

📋 問題

名前は必須、その他の情報は任意で受け取り、全て表示する関数を作りましょう(**kwargsを使用)。

解答を見る

コード

※スマートフォンでは横スクロールできます

# name: 必須、**info: 任意
def show_user_info(name, **info):
    print(f"名前: {name}")
    for key, value in info.items():
        print(f"{key}: {value}")

show_user_info("太郎", age=15, city="東京", hobby="サッカー")

実行結果

名前: 太郎
age: 15
city: 東京
hobby: サッカー

問題8:ローカル変数の確認(中級)

📋 問題

関数の中でローカル変数xを10に設定し、関数の外でグローバル変数xを100に設定。それぞれ表示してみましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

# グローバル変数
x = 100

def test_scope():
    # ローカル変数(同じ名前だが別物)
    x = 10
    print(f"関数内: {x}")

test_scope()
print(f"関数外: {x}")

実行結果

関数内: 10
関数外: 100

問題9:統計情報を計算(上級)

📋 問題

*argsで数値を受け取り、合計、平均、最大値、最小値を辞書で返す関数を作りましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

def statistics(*numbers):
    if len(numbers) == 0:
        return {}
    
    return {
        "合計": sum(numbers),
        "平均": sum(numbers) / len(numbers),
        "最大": max(numbers),
        "最小": min(numbers)
    }

result = statistics(5, 10, 3, 8, 12)
for key, value in result.items():
    print(f"{key}: {value}")

実行結果

合計: 38
平均: 7.6
最大: 12
最小: 3

問題10:カウンター関数(上級)

📋 問題

グローバル変数を使って、関数が呼ばれた回数をカウントする関数を作りましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

# グローバル変数
call_count = 0

def counter():
    global call_count  # グローバル変数を変更する宣言
    call_count += 1
    print(f"{call_count}回目の呼び出し")

counter()
counter()
counter()

実行結果

1回目の呼び出し
2回目の呼び出し
3回目の呼び出し

問題11:計算機関数(上級)

📋 問題

演算子と数値を可変長で受け取り、計算結果を返す関数を作りましょう。

例: calc(“+”, 1, 2, 3) → 6

解答を見る

コード

※スマートフォンでは横スクロールできます

def calc(operation, *numbers):
    if len(numbers) == 0:
        return 0
    
    result = numbers[0]
    
    for num in numbers[1:]:
        if operation == "+":
            result += num
        elif operation == "-":
            result -= num
        elif operation == "*":
            result *= num
        elif operation == "/":
            result /= num
    
    return result

print(calc("+", 1, 2, 3, 4))  # 1+2+3+4 = 10
print(calc("*", 2, 3, 4))     # 2*3*4 = 24

実行結果

10
24

問題12:全部入り関数(上級)

📋 問題

必須引数、デフォルト引数、*args、**kwargsを全て使う関数を作りましょう。

解答を見る

コード

※スマートフォンでは横スクロールできます

# 引数の順番: 必須 → デフォルト → *args → **kwargs
def super_function(required, default="デフォルト", *args, **kwargs):
    print(f"必須: {required}")
    print(f"デフォルト: {default}")
    print(f"追加引数: {args}")
    print(f"キーワード: {kwargs}")

super_function(
    "必須値",
    "カスタム",
    1, 2, 3,
    key1="値1", key2="値2"
)

実行結果

必須: 必須値
デフォルト: カスタム
追加引数: (1, 2, 3)
キーワード: {'key1': '値1', 'key2': '値2'}

❓ よくある質問

Q1: デフォルト引数はいつ使うべき?

よく使う値がある時や、オプション的な引数がある時に便利です。

例:サーバー設定でポート番号を指定する時、多くの場合は8000を使うなら、デフォルト値を8000にします。

Q2: *argsと**kwargsは一緒に使える?

はい、使えます!順番は「普通の引数」→「*args」→「**kwargs」の順です。

Q3: グローバル変数は使わない方がいい?

できるだけ使わない方が良いです。

関数は引数と戻り値でやり取りする方が、バグが少なく、テストしやすいコードになります。

Q4: デフォルト引数にリストを使っていい?

注意が必要です!デフォルト引数のリストは全ての呼び出しで共有されます。

リストを使いたい時は、Noneをデフォルトにして、関数内で新しいリストを作るのが安全です。

🎉 ステップ17のまとめ

✅ このステップで学んだこと

デフォルト引数def func(arg=デフォルト値)で省略可能な引数を作れる

キーワード引数func(arg=値)で名前を指定して渡せる

*args:可変個数の位置引数をタプルで受け取る

**kwargs:可変個数のキーワード引数を辞書で受け取る

スコープ:ローカル変数とグローバル変数の違いを理解

globalは最小限に、引数と戻り値を使おう

💪 次のステップへ

関数の応用をマスターしました!

これで、柔軟で使いやすい関数を作れるようになりました。

次のステップでは、lambda関数と組み込み関数を学びます。

短い関数を簡潔に書く方法や、Pythonに標準で用意されている便利な関数を使いこなしましょう!

📝

学習メモ

Pythonプログラミング基礎 - Step 17

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE