Pythonを書き始めたばかりの頃は、動くコードを書けるだけでうれしいものです。
最初はそれで大丈夫です。まず動かすことは、とても大切です。
でも、少し慣れてくると、同じような処理を何度も書いていることに気づくかもしれません。
このコード、さっきも書いた気がする。 少しだけ違う処理を何回もコピーしている。
そんな経験はありませんか。
そのときに考えたいのが、関数化です。
関数化とは、よく使う処理をひとまとまりにして、名前をつけて再利用できるようにすることです。Pythonでは def を使って関数を作ります。
この記事では、Python初心者向けに、同じ処理を何度も書いてしまう原因や、関数化するタイミング、関数化するときの考え方をわかりやすく解説します。
関数化とは何か¶
まずは、関数化という言葉を整理しておきましょう。
関数化というと少し難しく聞こえますが、考え方はシンプルです。
処理に名前をつけて再利用すること¶
関数化とは、ひとまとまりの処理に名前をつけて、何度も使えるようにすることです。
たとえば、税込価格を計算する処理を考えてみます。
price = 1000
tax_price = price * 1.1
print(tax_price)
この処理を何度も使うなら、関数にできます。
def add_tax(price):
return price * 1.1
print(add_tax(1000))
print(add_tax(2500))
add_tax という名前をつけたことで、税込価格を計算する処理を何度も使えるようになりました。
これが関数化の基本です。
関数は処理の部品¶
関数は、プログラムの中の部品のようなものです。
料理でたとえるなら、材料を切る、炒める、盛り付けるといった作業を分けるイメージです。
すべての作業を一気に書くと、何をしているのかわかりにくくなります。
でも、作業ごとに名前をつけると、流れを読みやすくできます。
Pythonでも同じです。
処理を関数に分けることで、コードの見通しがよくなります。
なぜ同じ処理を何度も書いてしまうのか¶
関数化を学ぶ前に、なぜ同じ処理を何度も書いてしまうのかを考えてみましょう。
これは初心者だけの問題ではありません。実務でも、忙しいときや設計があいまいなときに起こります。
とりあえず動かすことを優先するから¶
初心者のうちは、とにかく動かしたい気持ちが強いです。
最初からきれいなコードを書こうとしすぎると、手が止まってしまいます。
たとえば、3人分の合計金額を表示するコードを書いたとします。
price1 = 1000
tax_price1 = price1 * 1.1
print(tax_price1)
price2 = 1500
tax_price2 = price2 * 1.1
print(tax_price2)
price3 = 2000
tax_price3 = price3 * 1.1
print(tax_price3)
このコードは動きます。
でも、同じような処理が3回出てきます。こういうときに、あとから関数化を考えるとよいです。
少し違う処理に見えるから¶
同じ処理に見えないこともあります。
たとえば、名前の表示、商品名の表示、ユーザー名の表示など、一見すると違う処理に見えるかもしれません。
print("田中さん、こんにちは")
print("佐藤さん、こんにちは")
print("鈴木さん、こんにちは")
でも、よく見ると、違うのは名前だけです。
この場合は、名前を引数として受け取る関数にできます。
def greet(name):
print(name + "さん、こんにちは")
greet("田中")
greet("佐藤")
greet("鈴木")
関数化では、変わる部分と変わらない部分を分けることが大切です。
関数化するタイミング¶
では、どのタイミングで関数化すればよいのでしょうか。
初心者が一番迷うのはここだと思います。
同じ処理が2回出てきたら気にする¶
よく、同じ処理が3回出てきたら関数化を考えると言われることがあります。
これは目安としてわかりやすいです。
ただ、初心者の場合は、2回出てきた時点で一度立ち止まるくらいでちょうどよいです。
すぐに関数化しなくても構いません。
この処理は今後も使いそうか。少し変えれば共通化できるか。修正するときに面倒になりそうか。
そう考えるだけでも、コードの見方が変わります。
処理の意味を名前で表せるとき¶
関数化しやすいタイミングは、処理に名前をつけられるときです。
たとえば、税込価格を計算する、ユーザーにあいさつする、平均点を計算する、入力値をチェックする。
こうした名前が自然に浮かぶ処理は、関数にしやすいです。
def calculate_average(scores):
return sum(scores) / len(scores)
scores = [80, 70, 90]
print(calculate_average(scores))
calculate_average という名前を見るだけで、平均を計算する処理だとわかります。
このように、関数名が処理の説明になると、コードが読みやすくなります。
修正が複数箇所に広がりそうなとき¶
同じ処理を何度も書いていると、修正が大変になります。
たとえば、消費税率を10%から8%に変えたい場合を考えます。
price1 = 1000 * 1.1
price2 = 2000 * 1.1
price3 = 3000 * 1.1
この場合、全部の 1.1 を修正しなければいけません。
もし1か所だけ直し忘れると、バグになります。
関数化しておけば、修正箇所を1つにできます。
def add_tax(price):
return price * 1.1
print(add_tax(1000))
print(add_tax(2000))
print(add_tax(3000))
税率を変えるときは、関数の中だけ直せば済みます。
関数化の判断を表で整理¶
ここで、関数化を考えるタイミングを表で整理してみましょう。
初心者のうちは、感覚だけで判断するのが難しいので、こうした基準を持っておくと便利です。
| 状況 | 関数化を考えるべきか | 理由 |
|---|---|---|
| 同じ処理が2回以上出てきた | 考える | 今後さらに増える可能性がある |
| 処理に名前をつけられる | 考える | コードの意味が読みやすくなる |
| 修正箇所が複数に広がる | かなりおすすめ | 直し忘れを防げる |
| 一度しか使わない短い処理 | 無理にしなくてよい | かえって読みにくくなることもある |
| 処理が長くて読みにくい | 考える | 役割ごとに分けると見通しがよくなる |
| 変わる部分だけ違う | おすすめ | 引数で共通化しやすい |
関数化は、やればやるほど良いわけではありません。
でも、同じ処理を何度も書いているなら、まず関数化の候補として見てみましょう。
関数化の基本パターン¶
ここからは、具体的な関数化のパターンを見ていきます。
難しいテクニックではなく、初心者が最初に覚えておきたい基本です。
値を受け取って結果を返す¶
一番よく使うのが、引数で値を受け取り、returnで結果を返すパターンです。
def add_tax(price):
return price * 1.1
result = add_tax(1000)
print(result)
price が引数です。
関数の外から値を受け取り、計算した結果を return で返しています。
この形を覚えると、かなり多くの処理を関数化できます。
表示する処理をまとめる¶
printを含む処理をまとめることもできます。
def show_user(name, age):
print("名前:", name)
print("年齢:", age)
show_user("田中", 20)
show_user("佐藤", 25)
このようにすると、ユーザー情報の表示処理をまとめられます。
表示形式を変えたいときも、関数の中だけ修正すれば済みます。
チェック処理をまとめる¶
入力値のチェックも関数化しやすい処理です。
def is_adult(age):
return age >= 18
print(is_adult(20))
print(is_adult(15))
この関数は、年齢が18歳以上ならTrueを返します。
条件式をそのまま何度も書くより、is_adult という名前にすることで意味が伝わりやすくなります。
関数化するときに考えること¶
関数化するときは、ただコードを切り出せばよいわけではありません。
読みやすい関数にするためには、いくつか意識したいポイントがあります。
変わる部分を引数にする¶
関数化で大切なのは、変わる部分を引数にすることです。
たとえば、あいさつ文の中で名前だけが変わるなら、名前を引数にします。
def greet(name):
print(name + "さん、こんにちは")
商品の価格だけが変わるなら、価格を引数にします。
def add_tax(price):
return price * 1.1
このように、何が毎回変わるのかを見ると、引数にすべきものが見えてきます。
関数名で何をするかわかるようにする¶
関数名はとても大切です。
func1 や do_something のような名前だと、何をする関数なのかわかりません。
def calc_total(price, count):
return price * count
この名前なら、合計を計算する関数だとわかります。
さらにわかりやすくするなら、次のようにしてもよいです。
def calculate_total_price(price, count):
return price * count
少し長くても、意味が伝わる名前の方が実務では助かります。関数名がわかりやすいコードはレビューしやすいです。
1つの関数に役割を詰め込みすぎない¶
関数は便利ですが、何でも詰め込むと逆に読みにくくなります。
たとえば、入力を受け取り、計算し、保存し、表示する処理を全部1つの関数に入れると、何をする関数なのかわかりにくくなります。
関数は、できるだけ1つの役割に絞ると読みやすいです。
入力する関数、計算する関数、表示する関数のように分けると、あとから修正しやすくなります。
関数化しない方がよい場合もある¶
ここまで関数化のメリットを話してきましたが、何でも関数化すればよいわけではありません。
初心者がよくやりがちなのは、短すぎる処理まで無理に関数にしてしまうことです。
一度しか使わない処理は無理に分けなくてよい¶
一度しか使わない短い処理は、無理に関数化しなくても大丈夫です。
name = "田中"
print(name)
この程度の処理を関数にすると、かえって読む場所が増えてしまいます。
もちろん、意味のある処理なら関数化してもよいです。
ただ、関数化の目的はコードを複雑にすることではありません。読みやすく、直しやすくすることです。
名前をつけにくい処理はまだ整理できていない¶
関数名がうまくつけられない場合は、処理のまとまりがまだ整理できていない可能性があります。
そのときは、無理に関数化する前に、処理をよく読んでみましょう。
この部分は入力なのか。計算なのか。表示なのか。保存なのか。
役割を分けると、自然に名前が見えてくることがあります。
関数化の実践例¶
ここで、少し実践的な例を見てみましょう。
同じような処理が何度も出てくるコードを、関数化していきます。
関数化前のコード¶
次のコードでは、3人分の点数を判定しています。
score1 = 85
if score1 >= 80:
print("よくできました")
elif score1 >= 60:
print("合格です")
else:
print("復習しましょう")
score2 = 70
if score2 >= 80:
print("よくできました")
elif score2 >= 60:
print("合格です")
else:
print("復習しましょう")
score3 = 45
if score3 >= 80:
print("よくできました")
elif score3 >= 60:
print("合格です")
else:
print("復習しましょう")
動きますが、同じ判定処理が3回出てきます。
もし基準点を変えたい場合、3か所修正しなければいけません。
関数化後のコード¶
判定処理を関数にすると、次のように書けます。
def judge_score(score):
if score >= 80:
return "よくできました"
elif score >= 60:
return "合格です"
else:
return "復習しましょう"
print(judge_score(85))
print(judge_score(70))
print(judge_score(45))
かなり読みやすくなりました。
judge_score という関数名を見るだけで、点数を判定する処理だとわかります。
修正したいときも、関数の中だけ見ればよいです。
関数化のコツ¶
ここからは、実務や育成で感じてきたことを少し話します。
関数化は、初心者が中級者へ進むときの大きなステップです。
最初から完璧に関数化しなくてよい¶
初心者のうちは、最初からきれいに関数化しようとしなくて大丈夫です。
まずはベタ書きで動かす。次に、同じ処理を見つける。最後に、関数に切り出す。
この順番で十分です。
いきなり設計を完璧にしようとすると、何を書けばいいのかわからなくなります。
実務でも、最初から完璧なコードを書くより、動くものを作ってから整理することはよくあります。
関数化は未来の自分への思いやり¶
関数化は、今の自分のためだけではありません。
未来の自分や、チームの人のためでもあります。
1か月後に自分のコードを読み返したとき、関数名がわかりやすければ、何をしているのか思い出しやすいです。
逆に、同じ処理が何度もコピーされていると、どこを直せばよいのか迷います。
関数化は、コードを読む人への思いやりです。
レビューで見られるのは処理の分け方¶
コードレビューでは、動くかどうかだけでなく、処理の分け方も見られます。
この処理は関数にした方が読みやすい。この関数は役割が多すぎる。この名前だと意味が伝わりにくい。
こうした指摘は、初心者のうちは少し難しく感じるかもしれません。
でも、関数化を意識できるようになると、コードの見方が一段上がります。
関数化を練習する方法¶
最後に、関数化を身につけるための練習方法を紹介します。
難しいアプリを作らなくても、日常的な小さいコードで十分練習できます。
まずは計算処理を関数にする¶
最初におすすめなのは、計算処理です。
税込価格、平均点、合計金額、割引後の価格などは関数化しやすいです。
def calculate_discount_price(price, discount_rate):
return price * (1 - discount_rate)
print(calculate_discount_price(1000, 0.2))
この関数は、割引後の価格を計算します。
引数を変えると、いろいろな価格に使えます。
次に判定処理を関数にする¶
次におすすめなのは、判定処理です。
成人かどうか、合格かどうか、在庫があるかどうか、入力が空かどうか。
こうした処理は、関数にすると読みやすくなります。
def is_empty(text):
return text == ""
print(is_empty(""))
print(is_empty("Python"))
関数名が is_ で始まると、TrueかFalseを返す関数だとわかりやすいです。
最後に表示や入力を分ける¶
慣れてきたら、表示処理や入力処理も分けてみましょう。
def ask_name():
return input("名前を入力してください: ")
def show_greeting(name):
print(name + "さん、こんにちは")
name = ask_name()
show_greeting(name)
入力と表示を分けることで、それぞれの役割がはっきりします。
小さなコードでも、このように分ける練習をすると実務に近い考え方が身につきます。
まとめ:同じ処理を見つけたら関数化のチャンス¶
Pythonで同じ処理を何度も書いてしまうのは、初心者なら自然なことです。
最初からきれいに書けなくても大丈夫です。
大切なのは、あとからコードを見直して、同じ処理がないかを探すことです。
同じ処理が2回以上出てきたとき。処理に名前をつけられるとき。修正が複数箇所に広がりそうなとき。変わる部分だけが違うとき。
こうした場面は、関数化を考えるタイミングです。
関数化すると、コードの重複を減らせます。修正箇所を減らせます。処理の意味を名前で表せます。未来の自分やチームの人が読みやすいコードに近づきます。
もちろん、何でも関数にすればよいわけではありません。
一度しか使わない短い処理や、名前をつけにくい処理は、無理に関数化しなくても大丈夫です。
まずは、税込価格の計算、点数判定、あいさつ文の表示など、小さな処理から関数にしてみましょう。
関数化は、Python初心者が次の段階に進むための大事な考え方です。
動くコードから、読みやすく直しやすいコードへ。
その第一歩として、今日書いたコードの中に同じ処理がないか、少しだけ見直してみてください。