スポンサーリンク

Pythonの早期リターン入門|ifが深くなる原因と読みやすい改善パターン集

Python入門

Pythonを書いていると、いつの間にか if が何重にもネストしてしまい、「動いてはいるけど、正直読みたくないコード」になっていませんか?

特に初心者のうちは、仕様をそのまま条件分岐に落とし込もうとして、
「この中でさらに if、その中でまた if……」という構造になりがちです。

でも、安心してください。
それはセンスがないわけでも、理解力が足りないわけでもありません。

多くの場合、原因はただ一つ。
「条件をどう考えるか」という視点を、まだ知らないだけです。

この記事では、Pythonでよく使われる 早期リターン(Early Return / ガード節) という考え方を使って、

  • なぜ if が深くなってしまうのか
  • どう書き換えると一気に読みやすくなるのか
  • 初心者でも無理なく取り入れられる改善パターン

を、できるだけ噛み砕いて解説していきます。

コードを「正しく動かす」段階から、
「あとから見ても分かるコードを書く」段階へ進むための第一歩として、ぜひ読み進めてみてください 🙂


結論:早期リターンは「考え方」を変えるだけで効く

Pythonのコードが読みにくくなる一番の原因は、
if文の書き方そのものではなく、「条件の考え方」にあります。

多くの初心者は、

  • 条件を満たしていたら次へ進む
  • さらに条件を満たしていたら、その次へ進む

という思考でコードを書きます。 その結果、ifの中にif、その中にif……とネストが深くなってしまいます。

一方、早期リターンの考え方は真逆です。

「この条件を満たしていないなら、ここで終わり」
「ダメなケースは先に弾いてしまう」

こうして異常系・不要なケースを先に処理してしまうことで、
最後に残るのは「本当にやりたい処理」だけになります。

つまり早期リターンは、

  • 特別な構文テクニックではなく
  • 難しい文法でもなく
  • 考える順番を少し変えるだけ

それだけで、コードの見通しを一気に良くしてくれる方法です。

このあと、なぜifが深くなってしまうのか、
そして早期リターンでどう変わるのかを、順番に見ていきましょう。




なぜifが深くなってしまうのか

まず押さえておきたいのは、
ifが深くなるのは初心者あるあるで、かなり自然な流れだということです。

多くの場合、次のような思考でコードを書いています。

  • 条件Aを満たしていたら処理を続ける
  • その中で条件Bを満たしていたら次へ進む
  • さらに条件Cを満たしていたら……

これは一見、論理的で正しそうに見えます。
実際、「動くコード」はちゃんと書けています

ただ、この書き方には大きな落とし穴があります。

ネストが深いコードが抱える3つの問題

ifが深くなると、次のような問題が一気に表に出てきます。

  • 可読性の低下
    今どの条件の中にいるのかを、常に頭の中で追い続ける必要があります。
  • 保守性の低下
    条件を1つ追加・変更しただけで、どこに影響が出るのか分かりにくくなります。
  • バグの温床
    条件の組み合わせが増えすぎて、想定していない分岐が生まれやすくなります。

特に初心者のうちは、
「一度書いたコードをあとから直す」場面で、この問題が一気に表面化しがちです。

「ここに if を足せば動きそうだから……」と修正を重ねた結果、
気づけば自分でも全体像が分からなくなってしまう、というケースは本当によくあります。

コードの読みやすさがなぜ重要なのかについては、
次の記事でより体系的に解説しています。

では、この「ifが深くなる流れ」をどう断ち切ればいいのか。
そこで登場するのが、次に紹介する早期リターンです。




早期リターン(ガード節)とは何か

早期リターン(Early Return)やガード節(Guard Clauses)とは、
「条件を満たさない場合は、できるだけ早く関数を終了させる」書き方のことです。

ポイントは、「処理を進める条件を書く」のではなく、
「処理できない条件を先に弾く」という発想に切り替えることです。

たとえば初心者の方は、次のように考えがちです。

  • ログインしていたら処理する
  • 権限があったら処理する
  • 入力値が正しければ処理する

この考え方のまま書くと、自然と if の中に if を重ねる形になります。

一方、早期リターンではこう考えます。

  • ログインしていなければ終わり
  • 権限がなければ終わり
  • 入力値が不正なら終わり

つまり、「ダメなケースを先に全部片付ける」わけです。

このようにガード節を関数の冒頭に並べておくと、
それらをすべて通過した時点で、

「ここに来たなら、もう条件は整っている」

という状態が保証されます。

その結果、関数の後半にはインデントのない形で
本当にやりたいメイン処理だけを書くことができます。

なお、ここでよくある誤解がひとつあります。

「returnは1つだけにすべきでは?」という疑問です。

Pythonでは、可読性が上がるのであれば、
関数内に複数の return を置くことは一般的に問題ありません。

むしろ、早期リターンを使うことで、
「どんな場合に処理が終わるのか」が明確になり、
結果的にコード全体が読みやすくなるケースが多いです。

次は、実際のコードを見ながら、
早期リターンでネストがどう変わるのかを確認していきましょう。




早期リターンでネストが消える実例

ここでは、初心者がよく書きがちな「ifが深くなったコード」と、
それを早期リターンで書き直した例を比べてみます。

before:ifが何重にもなってしまうコード


def process_order(user, order):
    if user is not None:
        if user.is_active:
            if order is not None:
                if order.is_valid():
                    # メイン処理
                    execute_order(order)

このコード、動きはします。 でも読む側は、

  • 今どの条件の中にいるのか
  • どれか1つでも false だったら何が起きるのか

を、常に頭の中で追い続けなければなりません。

after:早期リターンを使ったコード


def process_order(user, order):
    if user is None:
        return
    if not user.is_active:
        return
    if order is None:
        return
    if not order.is_valid():
        return

    # メイン処理
    execute_order(order)

どうでしょうか。

インデントが一気に浅くなり、
上から順に読んでいくだけで処理の流れが分かるようになっています。

この形だと、

  • どんな場合に処理が終わるのか
  • どんな状態ならメイン処理に到達するのか

がとても明確です。

ここで大事なのは、
「早期リターンは書き方のテクニックではない」という点です。

これは、

条件をどう分解し、どういう順番で考えるか

という、いわば計算論的思考の話でもあります。

「なぜこの順で条件を並べるのか」「どこで処理を打ち切るべきか」 といった考え方をもう少し体系的に学びたい場合は、 次のような書籍がとても参考になります。

計算論的思考を育むPythonプログラミング入門
✅ Amazonでチェックする✅ 楽天でチェックする

次は、早期リターンを使うと
なぜ else を書かなくてよくなるのかを見ていきます。




elseを書かなくてよくなる理由

早期リターンを使い始めると、
自然と else を書かなくなることに気づくと思います。

これは偶然ではなく、早期リターンの考え方と構造が、
else を不要にするからです。

まず、よくある if / else の形を見てみましょう。


def check_value(x):
    if x > 0:
        result = x * 2
    else:
        return None

    return result

このコードでは、「条件を満たさない場合の処理」を
else の中に閉じ込めています。

一方、早期リターンを使うとこうなります。


def check_value(x):
    if x <= 0:
        return None

    return x * 2

処理の流れが、とても単純になりました。

重要なのは、
条件に当てはまらないケースは、そこで処理を終えてしまっている点です。

そのため、

  • else の中で何が起きているかを覚える必要がない
  • if と else を行ったり来たりせずに読める

という状態になります。

早期リターンを徹底すると、

  • if は「チェック専用」
  • return 以降は「メイン処理」

という役割分担が自然にできあがります。

この構造に慣れてくると、
「この if、else 本当に必要かな?」と考える癖がついてきます。

次は、早期リターンだけでは足りなくなったときに使える、
関数分割との組み合わせについて見ていきましょう。




早期リターンと関数分割の組み合わせ

早期リターンを使っても、
「まだちょっと読みにくいな…」と感じる場面があります。

それは、if の中身そのものが長くなってきたときです。

たとえば、

  • 条件を満たしたあとにやる処理が多い
  • 処理の途中でさらに分岐が出てくる
  • コメントを書かないと意図が伝わらない

こうなってきたら、
早期リターン + 関数分割を組み合わせるタイミングです。

判断と処理を分ける

関数設計でよくある失敗は、
「判断」と「処理」を1つの関数に詰め込んでしまうことです。

たとえば、こんなイメージです。


def handle_order(user, order):
    if user is None:
        return
    if not user.is_active:
        return
    if order is None:
        return
    if not order.is_valid():
        return

    # ここから処理が長い…
    send_mail(order)
    update_database(order)
    log_history(order)

この場合、ガード節自体は読みやすいですが、
後半の処理が増えるほど、関数の役割がぼやけてきます。

そこで、「処理」を外に追い出します。


def handle_order(user, order):
    if user is None:
        return
    if not user.is_active:
        return
    if order is None:
        return
    if not order.is_valid():
        return

    execute_order(order)


def execute_order(order):
    send_mail(order)
    update_database(order)
    log_history(order)

こうすることで、元の関数は

「条件をチェックして、問題なければ処理を呼ぶ」

という、非常に分かりやすい役割に集中できます。

関数名がコメントになる

もう一つ大きなメリットがあります。

それは、
関数名そのものが「何をしているか」の説明になることです。

長いコメントを書くよりも、


execute_order(order)

と書いてあるほうが、 読む側は一瞬で意図を理解できます。

この「return の意味」「関数の役割」をどう設計するかについては、
次の記事でかなり丁寧に解説しています。

次は、少し注意が必要なテーマです。
早期リターンを使いすぎると逆効果になるケースを見ていきましょう。




早期リターンを使いすぎると逆効果なケース

ここまで見ると、
「じゃあ早期リターンは多ければ多いほどいいの?」と思うかもしれません。

結論から言うと、
使いどころを間違えると、逆に読みにくくなることもあります。

return が散らばりすぎるケース

たとえば、こんなコードです。


def process(data):
    if data is None:
        return
    if not isinstance(data, dict):
        return
    if "value" not in data:
        return
    if data["value"] < 0:
        return
    if data["value"] == 0:
        return

    do_something(data)

条件自体はシンプルですが、
return がずらっと並ぶと、

  • どこまでがチェックなのか
  • 何が本当に重要な条件なのか

が分かりにくくなることがあります。

こういう場合は、

  • 条件をまとめる
  • チェック用の関数に切り出す

といった整理が有効です。

リソース管理が絡む場合は要注意

もう一つ注意したいのが、
ファイルやネットワークなどのリソースを扱う処理です。

途中で return すると、

  • ファイルが閉じられない
  • 後始末の処理が飛ばされる

といった事故が起きやすくなります。

Pythonでは、こうした問題を避けるために

  • with 構文
  • try / finally

を使って、
「return しても必ず後処理が走る構造」を作るのが基本です。

例外処理や return の使い分けについては、
次の記事で設計の視点から詳しく解説しています。

早期リターンは万能ではありません。
だからこそ、「使わない判断」も含めて設計だと考えることが大切です。

次は、早期リターンを
リファクタリングという視点で捉えてみましょう。




「リファクタリング」という視点で見る早期リターン

ここまで読んで、「なるほど、早期リターンは便利そうだな」と感じた方も多いと思います。

でも実は、早期リターンは単体のテクニックというより、
リファクタリングの入り口としてとても優秀な考え方です。

リファクタリングとは、ざっくり言うと

「動いているコードの振る舞いを変えずに、読みやすく・直しやすくすること」

です。

初心者のうちは、

  • とりあえず動かす
  • あとで直すのが怖い

という状態になりがちですが、
早期リターンは「壊しにくい改善」なので、最初の一歩としてとても向いています。

なぜなら、

  • 条件の順番を整理するだけ
  • 処理内容自体は変えない

という改善だからです。

実務では、
「とりあえず if を整理する」「ネストを浅くする」
という小さなリファクタリングが、結果的に大きな事故を防ぎます。

リファクタリングという考え方を、もう少し体系的に理解したい場合は、 次の定番書籍がとても参考になります。

リファクタリング
✅ Amazonでチェックする✅ 楽天でチェックする

次は、早期リターンを含めた設計をさらに一段引き上げる、 「ロバストな関数設計」について触れていきます。




もう一段上を目指す人へ:ロバストな関数設計

早期リターンと関数分割に慣れてくると、
次に気になってくるのが

「この関数、壊れにくいだろうか?」

という視点です。

ロバスト(robust)なコードとは、
入力が多少想定外でも破綻しにくく、
あとから仕様が変わっても修正しやすいコードのことを指します。

ロバストな関数の共通点

早期リターンをうまく使っている関数には、
次のような共通点があります。

  • 関数の冒頭で前提条件をすべてチェックしている
  • 「ここに来たら安全」という状態が保証されている
  • メイン処理がシンプルで短い

こうした関数は、

  • テストが書きやすい
  • バグが入り込みにくい
  • 他人が読んでも理解しやすい

という特徴を持ちます。

言い換えると、早期リターンは 「防御的にコードを書く」ための第一歩でもあります。

この考え方を、Python全体の設計思想としてさらに深く学びたい場合は、 次の書籍がとても参考になります。

ロバストPython ―クリーンで保守しやすいコードを書く
✅ Amazonでチェックする✅ 楽天でチェックする

ここまでで、早期リターンを軸にした 「読みやすく、壊れにくいコード」の全体像が見えてきたと思います。

次は、初心者が特につまずきやすい よくある誤解・注意点を整理していきます。




よくある誤解・初心者が勘違いしやすいポイント

早期リターンはとても便利ですが、
使い始めの頃にありがちな誤解もいくつかあります。

returnは1つだけにすべき?

これは本当によく聞かれる疑問です。

結論から言うと、
Pythonでは「returnは1つだけ」にこだわる必要はありません。

特に早期リターンを使う場合、 複数の return があることで

  • どこで処理が終わるのか
  • どんな条件がNGなのか

が明確になります。

「出口は1つ」という原則は、
歴史的な背景を持つ考え方ではありますが、 現代のPythonでは可読性のほうが重視される場面が多いです。

ネストが浅ければ良いコード?

ネストが浅いこと自体は良い傾向ですが、 それだけで「良いコード」とは言えません。

条件が分かりにくかったり、 returnの意図が読み取れなかったりすると、 かえって理解しづらくなることもあります。

大切なのは、

「読んだ人が、処理の流れを迷わず追えるか」

という視点です。

早期リターンは高速化のためのテクニック?

これもよくある勘違いです。

早期リターンによって処理が早く終わるケースはありますが、 主な目的はパフォーマンスではなく可読性と安全性です。

まずは「読みやすさ」「壊れにくさ」を優先し、 速度が問題になったときに最適化を考える、 という順番をおすすめします。




まとめ

この記事では、Pythonで if が何重にもなってしまう原因と、 それを解消するための早期リターン(ガード節)の考え方を見てきました。

ポイントを振り返ると、次の通りです。

  • if が深くなるのは、構文の問題ではなく「条件の考え方」の問題
  • ダメなケースを先に弾くことで、ネストは自然と浅くなる
  • 早期リターンは、returnを増やすテクニックではなく思考整理
  • 処理が長くなったら、関数分割と組み合わせる
  • 使いすぎには注意し、設計として判断する

大事なのは、 「ifが増えたら、設計を見直すサインかもしれない」 と気づけるようになることです。

最初から完璧なコードを書く必要はありません。 動いているコードを、少しずつ読みやすくしていく。 その最初の一歩として、早期リターンはとても取り入れやすい考え方です。

ぜひ、次に if を書くときは、 「この条件、先に return できないかな?」 と一度立ち止まって考えてみてください 🙂


参考文献


よくある質問(Q&A)

Q
早期リターンは初心者でも使っていいですか?
A

もちろん問題ありません。 むしろ、初心者のうちから「条件を整理する書き方」に慣れておくと、 後々のコードが格段に読みやすくなります。

Q
小さな関数でもreturnを複数使って大丈夫ですか?
A

はい。 関数が短く、意図が分かりやすいのであれば、 複数の return があっても可読性は下がりません。

「どんな条件で終わるのか」が一目で分かるかどうかを基準にすると判断しやすいです。

Q
チーム開発では早期リターンは嫌がられませんか?
A

チームのコーディング規約にもよりますが、 Pythonでは早期リターンは一般的で、 可読性向上のために推奨されるケースが多いです。

大切なのは、チーム内で書き方を揃え、 「なぜこの書き方にしているのか」を共有することです。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク