早期 return で読みやすく
早期 return で読みやすく とは
ガード節 (guard clause) を使ってネストを減らした関数を書く。本レッスンでは、早期 return で読みやすく の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
早期 return で読みやすく
条件分岐に慣れてくると、次に気になるのが「ネストの深さ」です。if の中にさらに if が入り、その中にまた if、という階層構造は、ロジックは正しくても 読みづらく バグの温床になります。これを防ぐ定番テクニックが ガード節 (guard clause) と呼ばれる早期 return のパターンです。本レッスンでは、文字列を受け取り、整数として安全に倍にして返す関数 safe_double を、ガード節を活用して書きます。
「失敗ケースは早く帰す、正常ケースは平坦に書く」 — これがガード節の合言葉です。
ネストが深いコードの問題
None チェックや空文字チェックを if でひたすらネストすると、本来やりたい処理がインデントの奥深くに埋もれます。
Python
def safe_double_nested(text):
if text is not None:
if text != "":
if text.lstrip("-").isdigit():
n = int(text)
return n * 2
else:
return 0
else:
return 0
else:
return 0最後の return n * 2 が深くインデントされていて、何重もの条件を脳内でアンドしないと「結局この行はどんな条件で実行されるのか」がわかりません。else の塊も大量に増えて、保守も大変です。
ガード節で書き換える
失敗・例外ケースを 先に弾く、つまり「条件を満たさないなら早めに return してしまう」と、本筋の処理を一番外側のインデントで書けます。
Python
def safe_double(text):
if text is None:
return 0
if text == "":
return 0
if not text.lstrip("-").isdigit():
return 0
n = int(text)
return n * 2書き換えた版では、return n * 2 がトップレベルにあり、本処理が一目でわかります。これがガード節の典型的なフォームです。
「else を使わずに return で帰す」ことで、関数の主目的が文末にすっきり残ります。
動きを追ってみる
safe_double("5") の流れを追うと、None でも空文字でもなく、"5".lstrip("-").isdigit() が True なので、3 つのガードを全部すり抜けて int("5") * 2 の 10 が返ります。一方 safe_double(None) は最初のガードで即 return 0、safe_double("abc") は 3 つ目のガードで return 0 になります。負の数 "-3" も lstrip("-") で先頭の - を取り除いてから isdigit を見るので、int("-3") * 2 の -6 が返ります。
図を見ると、ガード節が「失敗ルートを左に押し出して、本筋を右下に伸ばす」設計になっていることがわかります。
よくある間違い
- ガードの後に
elseを続けてしまう —returnした時点で関数を抜けるので、elseは不要です。書くと逆に意図が読みづらくなります。 - 数字判定を
isdigitだけで済ませる —"-3".isdigit()はFalseです。負号や小数点を含む場合はlstrip("-")などで前処理してから判定します。 - ガードを忘れて
intを呼ぶ — 想定外の値でint(text)を呼ぶとValueErrorになります。ガードの順序は「型と空・形 → 中身」の順が安全です。
ガード節を増やすほど関数の安全性は上がりますが、過剰なガードは可読性を逆に下げます。ドメインで「ありえる失敗」だけ書きましょう。
やってみよう
関数 safe_double(text) を完成させます。text が None、空文字、数字として解釈できない文字列のいずれかなら 0 を返し、整数として解釈できる場合は int(text) * 2 を返してください。"5", "-3", None, "", "abc", "100" などのケースで確認されます。書けたら、ガードを if の連なりではなく try / except で書く版にも挑戦してみると、後の例外ハンドリングの章につながります。
さらに、ガード節は関数だけでなくクラスのメソッドやループの中でも応用できます。たとえば for ループの先頭で「対象外のアイテムは continue で飛ばす」のもガード的な発想で、本処理の階層を下げないテクニックです。コードレビューで「インデントが深い」と指摘されたら、まずガード節で平坦にできないかを検討するのが定石です。読みやすいコードは、結果として保守コストを下げ、チームの生産性を高めます。
よくある質問
Q. このトピックは Python 以外の言語でも同じ書き方ですか?
A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。
Q. 実行してエラーが出た場合の対処は?
A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。
Q. 次のステップで何を学ぶべきですか?
A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。
次のレッスン
次は BMI 体型判定 で、ガード節 (guard clause) を使ってネストを減らした関数を書く を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 早期 return の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 早期 return とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- ガード節 (早期 return) を使う
- None / 空文字 / 数字でない文字列はすべて 0 を返す
- 数字として解釈できる場合は int に変換して 2 倍を返す
入出力例
test-cases.txt
safe_double("5") → 10
safe_double("100") → 200
safe_double("-3") → -6
safe_double(null) → 0
safe_double("") → 0
safe_double("abc") → 0