この記事では、プログラミング言語PythonにおけるPythonの関数定義について、基本から応用まで、まるで手を取るように解説していきます。
プログラムを書いていると、何度も同じようなコードを書く場面が出てきますよね?そんなとき、関数を知っていると、コードがびっくりするほどスッキリして、開発効率もグンと上がるんです。
この記事を読めば、関数って何?どうやって作るの?どう使うのが賢いの?といった疑問が全部解消されるはず。
この記事で学べることリスト
- 関数の基本的な意味と作るメリット
- Pythonでの関数の正しい書き方(def文の使い方)
- 関数に値を渡す引数の使い方(位置引数、キーワード引数、デフォルト値)
- 関数から値を受け取る戻り値(return文)の使い方
- 変数が使える範囲を示すスコープの考え方
- 関数定義でよく起こるエラーと解決方法
Pythonの関数定義とはそもそも何?
Pythonの関数、なんだか難しそうに聞こえるかもしれませんね。でも、心配ご無用!関数とは、簡単に言うと「一連の処理をひとまとめにして名前をつけたもの」です。
イメージとしては、料理の「レシピ」に近いかもしれません。例えば「カレーを作る」というレシピ(関数)があれば、材料(データ)さえ渡せば、いつでも美味しいカレー(結果)を作れますよね?毎回イチから手順を考えなくてもOKなんです。
関数を作るメリットはたくさんあります。
- コードの再利用
同じ処理を何度も書く必要がなくなり、関数を呼び出すだけで済むようになります。 - コードの可読性向上
処理内容に関数名が付くので、何をしているのか分かりやすくなります。長いプログラムもスッキリ! - 保守性の向上
処理内容を変更したい場合、関数の定義部分だけを修正すればOK。修正漏れのリスクも減ります。
関数は、プログラムを整理整頓するための、いわば「魔法の整理箱」みたいなものだと考えてくださいね。
なぜPythonの関数定義が必要?コードが劇的に変わる理由
関数を使わなくてもプログラムは書けます。でも、関数を使わないと、ちょっと困ったことが起きるかもしれません。
例えば、同じ計算をプログラムのあちこちで3回行う必要があったとしましょう。
関数を使わない場合
# 計算1 result1 = 10 + 5 print(result1) # ... いろんな処理 ... # 計算2(計算1と同じ内容) result2 = 10 + 5 print(result2) # ... また別の処理 ... # 計算3(計算1と同じ内容) result3 = 10 + 5 print(result3)
これだと、もし計算式を「10 + 6」に変えたくなったら、3箇所すべてを修正しないといけません。うっかり修正し忘れると、バグの原因になっちゃいます。
関数を使う場合
# 関数を定義する def add_numbers(): result = 10 + 5 print(result) # 計算1 add_numbers() # ... いろんな処理 ... # 計算2 add_numbers() # ... また別の処理 ... # 計算3 add_numbers()
どうでしょう?関数を一度定義しておけば、あとは `add_numbers()` と呼び出すだけで同じ計算ができます。
もし計算式を「10 + 6」に変えたくなっても、関数定義の中の1行を修正するだけでOK! コードも短く、見やすくなりましたよね?
これが、関数定義が必要な大きな理由です。コードが劇的に改善されるのを実感できるはず!
Pythonの関数定義の基本的な書き方defを使ってみよう
さあ、いよいよPythonで関数を定義する方法を見ていきましょう!
関数を定義するには、`def` というキーワードを使います。基本の形はこうです。
def 関数名(): # ここに実行したい処理を書く (インデントを忘れずに!) 処理1 処理2
- `def` 関数の定義を開始することを示します。
- `関数名` あなたが自由につけられる関数の名前です。後でこの名前を使って関数を呼び出します。
- `()` このカッコの中に、後で説明する「引数」というものを書くことがあります。何も受け取らない場合は空にします。
- `:` コロンを忘れずにつけます。ここから関数の本体が始まる合図です。
- `インデントされた処理` `def`の行より一段右に字下げ(インデント)して、関数が行う処理を記述します。インデントされている範囲が関数の本体です。
まずは、この基本の形をしっかり覚えちゃいましょう!
最もシンプルな関数の定義と呼び出し方
まずは、引数も戻り値もない、一番シンプルな関数を作ってみましょう。
「Hello Python!」と表示するだけの関数 `say_hello` を定義して、呼び出してみます。
# 「Hello Python!」と表示する関数を定義 def say_hello(): print("Hello Python!") # 関数を呼び出す print("関数を呼び出します。") say_hello() print("関数呼び出しが終わりました。")
表示結果
関数を呼び出します。 Hello Python! 関数呼び出しが終わりました。
どうですか? `def say_hello():` で関数を定義し、 `say_hello()` でその関数を呼び出しています。
呼び出されたタイミングで、関数の中の `print("Hello Python!")` が実行されているのが分かりますね。これが関数定義と呼び出しの基本です。
関数定義の際の命名規則と注意点
関数に名前を付けるときには、いくつかルールと、分かりやすくするためのコツがあります。
命名規則(ルール)
- 使える文字 英字(大文字・小文字)、数字、アンダースコア `_`
- 始まりの文字 数字は使えません。英字かアンダースコアで始める必要があります。
- 予約語は使えない `def`, `if`, `for`, `class` など、Pythonが特別な意味で使っている単語(予約語)は関数名に使えません。
- 大文字・小文字の区別 `myfunction` と `myFunction` は違う関数名として扱われます。
分かりやすい名前を付けるコツ(推奨)
- スネークケースを使う
単語と単語の間をアンダースコア `_` でつなぐ書き方です。(例 `calculate_total_price`)Pythonではこの書き方が一般的です。 - 動詞を含める
関数が何をするのかを示す動詞を含めると分かりやすくなります。(例 `get_user_name`, `calculate_sum`, `print_report`) - 具体的で分かりやすい名前
`func1` や `a` のような名前ではなく、処理内容が推測できる名前をつけましょう。
注意点
- インデントは超大事!
関数の処理内容は必ずインデント(通常は半角スペース4つ)してください。インデントがズレているとエラーになります。
分かりやすい名前を付けるのは、後で自分や他の人がコードを読んだときに、理解しやすくするためです。良い名前を付ける習慣を身につけましょう!
Pythonの関数定義における引数の使い方をマスター
先ほどの `say_hello` 関数は、いつ呼び出しても同じ「Hello Python!」と表示するだけでした。
でも、関数にデータを渡して、そのデータに応じた処理をさせたい場面がたくさんあります。
例えば、挨拶する相手の名前を変えたい、計算する数値を変えたい、などなど。
そんな時に使うのが「引数(ひきすう)」です!
引数とは、関数を呼び出すときに、関数に渡す値のことです。
関数を定義するときに、「この関数はこういう値を受け取りますよ」と宣言しておきます。
def 関数名(仮引数1, 仮引数2): # 仮引数1 や 仮引数2 を使った処理 処理
- 仮引数(かりひきすう) 関数定義の `()` の中に書く変数名です。関数の中で、呼び出し元から渡された値を受け取るために使います。
そして、関数を呼び出すときには、この仮引数に対応する値を渡します。
関数名(実引数1, 実引数2)
- 実引数(じつひきすう) 関数呼び出しの `()` の中に書く、実際に渡す値や変数のことです。
言葉だけだと分かりにくいので、具体的な例を見ていきましょう!
引数あり関数の定義と呼び出し方
では、名前を引数として受け取り、「こんにちは、〇〇さん!」と表示する関数 `greet` を作ってみましょう。
# 名前を受け取って挨拶する関数を定義 def greet(name): # name が仮引数 print(f"こんにちは、{name}さん!") # 関数を呼び出す(引数を渡す) greet("太郎") # "太郎" が実引数 greet("花子") # "花子" が実引数
表示結果
こんにちは、太郎さん! こんにちは、花子さん!
関数 `greet` は `name` という仮引数を一つ受け取るように定義されています。
`greet("太郎")` と呼び出すと、 `"太郎"` という実引数が `name` に渡され、関数の中では `name` が `"太郎"` として扱われます。
`greet("花子")` の場合も同様に `name` が `"花子"` になります。
このように、引数を使うことで、関数に渡す値を変えて、処理の内容を柔軟に変えることができますね!
複数の引数を受け取ることもできます。カンマ `,` で区切って定義します。
# 2つの数値を受け取って合計を表示する関数 def add_two_numbers(num1, num2): # num1, num2 が仮引数 total = num1 + num2 print(f"{num1} と {num2} の合計は {total} です。") # 関数を呼び出す add_two_numbers(5, 3) # 5と3を渡す add_two_numbers(100, 200) # 100と200を渡す
表示結果
5 と 3 の合計は 8 です。 100 と 200 の合計は 300 です。
位置引数とキーワード引数の違いと使い分け
関数に引数を渡す方法には、主に2種類あります。「位置引数」と「キーワード引数」です。
- 位置引数
引数を渡す順番で、どの仮引数に対応するか決まります。これまで見てきた例はすべて位置引数です。 - キーワード引数
`仮引数名=値` という形で、どの仮引数にどの値を渡すか名前で指定します。
先ほどの `add_two_numbers` 関数を例に見てみましょう。
位置引数での呼び出し(これまでと同じ)
add_two_numbers(5, 3) # 1番目の5がnum1に、2番目の3がnum2に渡される
キーワード引数での呼び出し
add_two_numbers(num1=5, num2=3) # num1に5、num2に3を渡す add_two_numbers(num2=3, num1=5) # 順番を変えてもOK!num1に5、num2に3を渡す
キーワード引数のメリットは、
- 引数の順番を気にしなくてよい。
- どの引数にどの値が渡されているか、コードが分かりやすくなる。
という点です。特に引数が多い関数を呼び出すときは、キーワード引数を使うと、コードの可読性が格段に向上します。
使い分けの目安
- 引数が少ない(1~2個)場合は、位置引数でも分かりやすいことが多いです。
- 引数が3個以上ある場合や、引数の意味が名前を見ないと分かりにくい場合は、キーワード引数の使用を検討しましょう。
両方を混ぜて使うこともできますが、その場合は位置引数を先に書き、その後にキーワード引数を書く必要があります。
# OKな例 # def func(a, b, c): ... # func(10, c=30, b=20) # NGな例(キーワード引数の後に位置引数は書けない) # func(a=10, 20, 30) --> エラーになる
デフォルト引数値を設定する方法
関数を呼び出すときに、毎回同じ値を指定することが多い引数ってありますよね。
そんなときには、関数を定義する際に「デフォルト引数値」を設定しておくと便利です。
デフォルト引数値とは、関数呼び出し時にその引数が省略された場合に、自動的に使われる値のことです。
定義の仕方は、仮引数名の後に `=デフォルト値` を付けます。
def 関数名(引数1, 引数2=デフォルト値): # 処理 pass
例として、挨拶する関数 `greet` で、敬称をオプションとして付けられるようにし、デフォルトでは「さん」を使うようにしてみましょう。
# 敬称のデフォルト値を「さん」にした挨拶関数 def greet_with_title(name, title="さん"): # titleのデフォルト値を設定 print(f"こんにちは、{name}{title}!") # 関数を呼び出す greet_with_title("太郎") # titleを省略 → デフォルト値「さん」が使われる greet_with_title("花子", "様") # titleを指定 → 指定した「様」が使われる greet_with_title("健太", "くん") # titleを指定 → 指定した「くん」が使われる
表示結果
こんにちは、太郎さん! こんにちは、花子様! こんにちは、健太くん!
`greet_with_title("太郎")` の呼び出しでは、`title` 引数が省略されていますが、デフォルト値の「さん」が自動的に使われていますね。
このように、デフォルト引数を設定しておくと、よく使う値の場合は引数を省略できて、呼び出しがシンプルになります。
注意点
デフォルト引数を設定する仮引数は、設定しない仮引数よりも後ろに書く必要があります。
# OKな例 def func(a, b=10, c=20): pass # NGな例(デフォルト値ありの引数の後に、なしの引数は書けない) # def func(a=10, b, c=20): pass --> エラーになる
Pythonの関数定義で戻り値returnを理解する
これまでの関数は、計算結果などを `print()` で表示するだけでした。
でも、関数で計算した結果を、関数の外で変数に保存したり、別の計算に使ったりしたい場合がありますよね。
そんなときに使うのが「戻り値(もどりち)」と`return`文です!
戻り値とは、関数が処理を終えた後に、呼び出し元(関数を呼び出した場所)に返す値のことです。
関数内で `return 値` と書くと、その値が関数の戻り値となります。
def 関数名(引数): # 何かの処理... 計算結果 = ... return 計算結果 # この値が関数の呼び出し元に返される
`return` 文が実行されると、その時点で関数の処理は終了し、値が返されます。`return` 文の後に関数の処理が書かれていても、それは実行されません。
もし関数内で `return` 文が実行されない場合(`return` がない関数、または条件分岐などで `return` を通らなかった場合)、関数は特別な値 `None` を返します。`None` は「何もない」ことを表す値です。
戻り値あり関数の定義と使い方
では、2つの数値を受け取って、その合計を戻り値として返す関数 `calculate_sum` を作ってみましょう。
# 2つの数値の合計を返す関数 def calculate_sum(num1, num2): total = num1 + num2 return total # 計算結果 total を戻り値として返す # 関数を呼び出して、戻り値を受け取る result = calculate_sum(15, 8) # 戻り値が変数 result に代入される print(f"15と8の合計は {result} です。") # 戻り値を直接別の処理に使うこともできる another_result = calculate_sum(10, 5) * 2 # 戻り値(15)を2倍する print(f"10と5の合計の2倍は {another_result} です。")
表示結果
15と8の合計は 23 です。 10と5の合計の2倍は 30 です。
`calculate_sum(15, 8)` を呼び出すと、関数内で計算された合計 `23` が `return` され、変数 `result` に代入されていますね。
また、`calculate_sum(10, 5)` の戻り値 `15` を直接 `* 2` の計算に使っている例もあります。
このように、`return` を使うことで、関数の処理結果を外で活用できるようになります!これが戻り値の大きな利点です。
複数の値を返す方法タプルやリストを活用
関数から返したい値が一つだけとは限りませんよね。例えば、計算結果と、計算が成功したかどうかのフラグを両方返したい、なんてことも…。
Pythonの関数では、`return` で複数の値を同時に返すことができます!
やり方は簡単で、`return` の後に返したい値をカンマ `,` で区切って書くだけです。
def 関数名(): 値1 = ... 値2 = ... return 値1, 値2
こうすると、関数はこれらの値を「タプル」というデータ型にまとめて返します。タプルは、複数の要素を順番に保持できる、カッコ `()` で囲まれたようなデータ型です(カッコは省略されることもあります)。
返された複数の値は、呼び出し元で複数の変数を使って、それぞれ受け取ることができます。
変数1, 変数2 = 関数名()
例として、2つの数値を受け取り、その合計と平均の両方を返す関数を作ってみましょう。
# 合計と平均を計算して両方返す関数 def calculate_sum_and_average(num1, num2): total = num1 + num2 average = total / 2 return total, average # 合計と平均をカンマ区切りで返す # 関数を呼び出して、複数の戻り値を受け取る sum_result, avg_result = calculate_sum_and_average(10, 20) print(f"合計: {sum_result}") print(f"平均: {avg_result}") # タプルとして受け取ることもできる result_tuple = calculate_sum_and_average(5, 15) print(f"戻り値のタプル: {result_tuple}") print(f"タプルの最初の要素(合計): {result_tuple[0]}")
表示結果
合計: 30 平均: 15.0 戻り値のタプル: (20, 10.0) タプルの最初の要素(合計): 20
`return total, average` で合計と平均の2つの値が返され、`sum_result, avg_result = ...` のようにして、それぞれの変数で受け取れていますね。
リストなど、他の複数の要素を保持できるデータ型に入れて返すことも可能です。必要に応じて複数の結果をまとめて返せるのは、とても便利です。
Pythonの関数定義で気をつけるべきスコープとは
関数を使っていると、「あれ?この変数はどこで使えるんだっけ?」と疑問に思うことがあります。それを理解する鍵が「スコープ」です。
スコープとは、簡単に言うと「変数や関数名が参照(アクセス)できる有効範囲」のことです。
Pythonには主に2つのスコープがあります。
- ローカルスコープ
関数の中で定義された変数(仮引数も含む)が持つスコープです。その変数は、基本的にその関数の中だけで有効で、関数の外からはアクセスできません。関数が終了すると、ローカル変数は消えてしまうイメージです。 - グローバルスコープ
関数の外(プログラムのトップレベル)で定義された変数が持つスコープです。グローバル変数は、プログラムのどこからでもアクセスできます(ただし、推奨されない使い方もあります)。
簡単な例を見てみましょう。
# グローバルスコープ global_var = "私はグローバル変数です" def my_function(): # ローカルスコープ local_var = "僕はローカル変数だよ" print(local_var) # OK: 関数内からローカル変数にアクセス print(global_var) # OK: 関数内からグローバル変数にアクセス # 関数の呼び出し my_function() # 関数の外からアクセス print(global_var) # OK: グローバル変数にアクセス # print(local_var) # NG: これはエラーになる!関数の外からローカル変数にはアクセスできない
表示結果
僕はローカル変数だよ 私はグローバル変数です 私はグローバル変数です
このように、関数の中で定義した `local_var` は関数の外からは見えません。一方、外で定義した `global_var` は関数の中からも外からも見えますね。
注意点
- 関数内でグローバル変数の値を変更したい場合
通常、関数内でグローバル変数と同じ名前の変数に値を代入しようとすると、それは新しいローカル変数が作られるだけです。もしグローバル変数の値を本当に変更したい場合は、関数内で `global 変数名` と宣言する必要があります。ただし、グローバル変数を関数内で変更するのは、プログラムの流れが分かりにくくなる原因になることが多いため、あまり推奨されません。 - 名前の衝突
ローカル変数とグローバル変数で同じ名前を使うと、関数内ではローカル変数が優先されます。意図しない挙動を避けるため、分かりやすい変数名を使い分けるのが良いでしょう。
スコープを理解することは、変数が予期せぬ場所で使われたり、書き換えられたりするのを防ぐために、とても大事な考え方です。
Pythonの関数定義でよくあるエラーとその対処法
プログラミングにエラーはつきもの。関数を定義したり呼び出したりするときにも、初心者が遭遇しやすい典型的なエラーがあります。
慌てずに対処できるよう、よくあるエラーとその原因、対処法を知っておきましょう!
【エラー例1】 `NameError: name '関数名 or 変数名' is not defined`
- 原因1 関数を呼び出す前に、その関数を定義していない。
- 原因2 関数名や変数名のスペルを間違えている。
- 原因3 スコープ外の変数を使おうとしている(例 関数の外からローカル変数を使おうとした)。
- 対処法 定義が呼び出しより前にあるか確認する。スペルミスがないかよく確認する。変数のスコープを確認する。
【エラー例2】 `TypeError: 関数名() takes X positional arguments but Y were given`
- 原因 関数を呼び出すときに渡した引数の数(Y個)が、関数定義で要求されている引数の数(X個)と合っていない。
- 対処法 関数定義を確認し、正しい数の引数を渡しているかチェックする。デフォルト引数値の設定なども確認する。
【エラー例3】 `TypeError: unsupported operand type(s) for +: 'int' and 'str'` (演算子や型は状況による)
- 原因 関数に渡した引数のデータ型が、関数内の処理で想定されている型と違う。(例 数値の足し算を期待しているのに文字列を渡してしまった)
- 対処法 関数に渡す引数のデータ型が正しいか確認する。関数内で型チェックや型変換を行うことも検討する。
【エラー例4】 `IndentationError: expected an indented block`
- 原因 `def` 文の後や、`if`, `for` などの後に続くべき処理のインデント(字下げ)がない、またはズレている。
- 対処法 コロン `:` の次の行から、処理内容を正しくインデント(通常は半角スペース4つ)する。インデントが揃っているか確認する。
エラーメッセージは、問題解決のための大きなヒントです。
エラーメッセージをよく読んで、何が問題なのかを特定する練習をしましょう。最初は戸惑うかもしれませんが、慣れてくるとエラー解決もスムーズにできるようになりますよ!
【まとめ】Pythonの関数定義をマスターしよう
この記事では、Pythonの関数定義について、基本的な考え方から具体的な書き方、引数や戻り値の使い方、そして注意点まで一通り解説してきました。
今回のポイントまとめ
- 関数は処理をまとめたもの。コードの再利用性、可読性、保守性を高める。
- `def` キーワードで関数を定義する。インデントが命!
- 引数を使うと、関数にデータを渡して処理を変えられる(位置引数、キーワード引数、デフォルト引数)。
- `return` 文で、関数の処理結果を呼び出し元に返すことができる(戻り値)。複数の値も返せる。
- スコープ(ローカル、グローバル)を意識して、変数が使える範囲を理解しよう。
- エラーメッセージは怖くない!原因を探るヒントが詰まっている。
関数を使いこなせるようになると、Pythonプログラミングがもっと効率的に、そしてもっと楽しくなるはずです!
今回学んだことを活かして、ぜひあなたのコードに関数を積極的に取り入れてみてください。
【関連記事】 「Pythonとは?」に答える最初の一歩
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。