🪆 ネスト地獄(Flat is better than nested)
🧭 はじめに
このページでは、Python の Zen Flat is better than nested に反する代表的アンチパターン 「ネスト地獄」 を扱います。
ネスト地獄は単なる「見た目の悪さ」ではありません。 処理の主筋が視覚的に失われ、理解・修正・検証のコストが指数関数的に増える という、構造的な欠陥です。
🎯 ねらい
- ネストが深くなるほど、認知負荷が爆発する理由を説明する
- 「平坦化」は好みではなく、設計上の安全策であることを示す
❓ 問題の定義
ネスト地獄とは、
if/for/tryが入れ子になり- 処理の本質がインデントの奥に沈む
- 全体像を把握するには最後まで読む必要がある
状態を指します。
ネストは分岐の数ではなく「組み合わせ」を増やします。 3段ネストは 3倍ではなく、理解コストが一気に跳ね上がります。
🤒 よくある症状
📐 インデントが右へ伸び続ける
- 画面幅の半分以上が空白
- ロジックが視界から消える
🧩 条件を最後まで読まないと意図が分からない
- 「結局この関数は何をしたいのか」が見えない
- 正常系と異常系の区別がつかない
🕳️ 重要な例外処理が深部に埋もれる
try/exceptがネストの底にある- エラー処理が後付けになっている
例外処理が深い位置にあるコードは、ほぼ確実に読まれません。
❌ 悪い例:実務でよく見る地獄
def handle_request(req):
if req:
if req.user:
try:
if req.user.is_active:
result = do_something(req)
if result:
return result
else:
log_error('no result')
else:
log_error('inactive user')
except Exception:
log_error('unexpected error')
else:
log_error('no user')
else:
log_error('no request')
問題点
- 正常系が最も深い場所にある
- エラー条件が主筋を覆い隠している
- 「成功した場合」が一番読みにくい
✅ 良い例①:ガード節で早期リターン
def handle_request(req):
if req is None:
log_error('no request')
return None
if req.user is None:
log_error('no user')
return None
if not req.user.is_active:
log_error('inactive user')
return None
try:
return do_something(req)
except Exception as e:
log_error(f'unexpected error: {e}')
return None
改善点
- 条件異常は最初に排除
- 正常系が最短距離で読める
- 処理の流れが上から自然に追える
ガード節は「条件分岐」ではなく「前提の明文化」です。
✅ 良い例②:分岐を関数に分解する
def validate_request(req):
if req is None:
raise ValueError('no request')
if req.user is None:
raise ValueError('no user')
if not req.user.is_active:
raise ValueError('inactive user')
def handle_request(req):
try:
validate_request(req)
return do_something(req)
except ValueError as e:
log_error(str(e))
return None
改善点
- 分岐が意味単位でラベル化
- ネストが構造的に消える
- 検証ロジックの再利用が可能
🧩 設計の要点
平坦化の基本原則
- 主筋(正常系)を一番上に置く
- 例外・エラーは「脇役」として早期に処理
- 深さではなく流れで読ませる
ネストを減らす代表手段
- ガード節(early return)
- 関数分割(意味で切る)
matchによる分岐の平坦化(必要な場合)
✅ チェックリスト
- インデントが 3段を超えていないか
- 正常系が 最短で読める構造か
- 例外処理が「深い場所」に沈んでいないか
- 条件分岐が「理由」ではなく「状態」で書かれていないか
🧠 まとめ
ネスト地獄は、
- 書いた瞬間は動く
- 修正時に壊れ
- 読み返した自分すら迷子になる
という時間差で効いてくるバグ生成器です。
Python の Zen が勧める Flat とは、
少ない行数ではなく、 思考の直線性を保つこと
次の記事では、 その「壊れているのに気づけない」代表例 🤐 例外の黙殺を扱います。