ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
基本形
try:
value = int(input("数値: "))
except ValueError as e:
print(f"数値ではありません: {e}")
else:
print(f"入力は {value} です") # 例外が出なかったときだけ
finally:
print("必ず実行される") # 成功でも失敗でも通る
| 節 | 実行されるタイミング |
|---|---|
try | 監視したい処理を置く。できるだけ短くする |
except | 指定した例外が起きたとき |
else | 例外が起きなかったとき |
finally | 例外の有無・return の有無に関わらず必ず |
複数の例外を捕まえる
try:
result = data["key"] / divisor
except KeyError:
result = 0 # 種類ごとに処理を変える
except ZeroDivisionError:
result = None
except (TypeError, ValueError) as e: # まとめて扱うときはタプル
print(f"型か値の問題: {e}")
except Exception as e: # 最後に広いものを置く
print(f"想定外: {e}")
raise # 対処できないので上へ投げ直す
狭い例外を先に、広い例外を後に書きます。except Exception を先頭に置くと以降の節に到達しません。
やってはいけない書き方
# 1. 裸の except
try:
do_something()
except: # KeyboardInterrupt / SystemExit まで捕まえる
pass # Ctrl + C でプログラムを止められなくなる
# 2. 握りつぶし
try:
save()
except Exception:
pass # 失敗が誰にも伝わらず、原因が永久に分からない
# 3. try の範囲が広すぎる
try:
conn = connect()
data = fetch(conn)
parsed = parse(data)
save(parsed)
except Exception:
print("失敗しました") # どこで失敗したか分からない
ログを残さない except: pass は、後から原因を追えなくする最悪のパターンです。握りつぶすなら、なぜ無視してよいのかをコメントで残します。
正しい捕まえ方
import logging
logger = logging.getLogger(__name__)
def load_config(path):
try:
with open(path, encoding="utf-8") as f: # 監視するのはこの 1 行だけ
text = f.read()
except FileNotFoundError:
logger.warning("設定ファイルが無いので既定値を使います: %s", path)
return {}
except OSError:
logger.exception("設定ファイルを読めませんでした") # トレースバック付き
raise # 呼び出し側に判断を委ねる
return parse(text)
logger.exception() は except の中でだけ使え、スタックトレースを自動で付けて ERROR で出力します。logger.error(str(e)) だと発生箇所が失われます。
例外を投げる
def withdraw(balance, amount):
if amount <= 0:
raise ValueError(f"金額は正の数にしてください: {amount}")
if amount > balance:
raise ValueError("残高が不足しています")
return balance - amount
# 原因を保ったまま別の例外に変換する
try:
config = load()
except OSError as e:
raise RuntimeError("起動に失敗しました") from e # 元の例外が __cause__ に残る
from e を付けると、表示に The above exception was the direct cause of... が出て元の原因まで辿れます。付け忘れると根本原因が消えます。
独自例外
class AppError(Exception):
"""このアプリの例外の基底クラス"""
class NotFoundError(AppError):
def __init__(self, resource_id):
super().__init__(f"{resource_id} が見つかりません")
self.resource_id = resource_id # 後から使える情報を持たせる
class ValidationError(AppError):
pass
try:
raise NotFoundError("user-42")
except AppError as e: # 自作例外だけまとめて捕まえられる
print(e) # user-42 が見つかりません
アプリ共通の基底クラスを 1 つ作ると、「自分たちが投げた例外」と「ライブラリが投げた例外」を区別できます。継承元は BaseException ではなく Exception にしてください。
finally と with
# finally で後始末
f = open("data.txt", encoding="utf-8")
try:
print(f.read())
finally:
f.close()
# with なら閉じ忘れない(推奨)
with open("data.txt", encoding="utf-8") as f:
print(f.read())
# finally の中の return は例外を消してしまう
def bad():
try:
raise ValueError("元の例外")
finally:
return "戻り値" # 例外が握りつぶされる。書かないこと
先に聞くか、後で謝るか
Python には、条件を確認してから実行する書き方(LBYL)と、まずやってみて失敗を拾う書き方(EAFP)の 2 通りがあります。Python では後者が標準的とされています。
import os
# LBYL: 事前に確認する
if os.path.exists(path):
with open(path) as f: # 確認と実行の間に消される可能性がある
data = f.read()
# EAFP: やってみて失敗を拾う(推奨)
try:
with open(path) as f:
data = f.read()
except FileNotFoundError:
data = ""
# 辞書の場合はどちらでもよいが、get のほうが短い
value = d["key"] if "key" in d else 0
value = d.get("key", 0)
事前確認は確認した瞬間と実行する瞬間の間に状態が変わり得るという弱点があります。ファイルやネットワークのように、他者が同時に触るものは EAFP が安全です。
複数の例外をまとめて扱う
from contextlib import suppress
# 無視してよいと分かっている例外だけを明示的に握りつぶす
with suppress(FileNotFoundError):
os.remove("temp.txt") # 無ければ無視でよい
# 複数の処理をまとめて実行し、失敗を集めて報告する
errors = []
for path in paths:
try:
process(path)
except Exception as e:
errors.append((path, e)) # 1 件失敗しても続行する
if errors:
for path, e in errors:
print(f"{path}: {type(e).__name__}: {e}")
raise RuntimeError(f"{len(errors)} 件の処理に失敗しました")
バッチ処理では「1 件失敗したら全部止める」か「失敗を記録して続行する」かを最初に決めます。suppress は「無視してよい」という意図をコードに残せる点が except: pass と違います。
リトライする
import time
def fetch_with_retry(url, attempts=3):
last = None
for i in range(1, attempts + 1):
try:
return fetch(url)
except (TimeoutError, ConnectionError) as e:
last = e
if i < attempts:
time.sleep(2 ** i) # 1 回目 2 秒、2 回目 4 秒
raise RuntimeError(f"{attempts} 回試して失敗しました") from last
再試行してよいのは一時的な失敗だけです。認証エラーや入力不正は何度やっても同じなので、対象の例外を絞ってください。
スタックトレースを文字列で受け取る
import traceback
try:
1 / 0
except ZeroDivisionError as e:
print(type(e).__name__) # ZeroDivisionError
print(str(e)) # division by zero
print(traceback.format_exc()) # 発生箇所まで含む全文
print(e.__traceback__.tb_lineno) # 行番号
例外を通知やレスポンスに載せるときは、利用者にはメッセージだけ、ログにはトレースバック全文と分けます。詳細は 例外を文字列で出力する方法 を参照してください。
主な組み込み例外
| 例外 | 起きる場面 |
|---|---|
ValueError | 型は合っているが値がおかしい(int("abc")) |
TypeError | 型が違う("1" + 1) |
KeyError | 辞書に無いキー |
IndexError | 範囲外の添字 |
AttributeError | 存在しない属性・メソッド(None に対する操作が多い) |
FileNotFoundError | ファイルが無い(OSError の一種) |
ZeroDivisionError | 0 で割った |
ImportError / ModuleNotFoundError | import に失敗 |
関連
- 文法 — 親カテゴリ
- 例外を文字列で出力する方法
- エラー一覧 — 実際のエラーと対処
- strからintへの型変換 —
ValueErrorの扱い - キーの存在チェック —
KeyErrorを避ける - 制御構文
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- 【django】ログイン 認証機能 2026-09-08 03:22:09
- MySQL ERROR 1063 Incorrect column specifier for column|原因と直し方 2026-09-08 03:11:09
- 【PHPエラー】Object of class stdClass could not be converted to string 2026-09-07 07:46:04
- Julia Genie ローカル開発サーバ起動完全ガイド 2026-09-07 07:46:04
- Wi-Fi とは|規格と世代(Wi-Fi 4〜7)・周波数帯・CSMA/CA・WPA3 NEW 2026-09-07 07:45:13
- set コマンドでシェルオプションと位置パラメータを操作 | bash 2026-09-07 07:45:13
- JPEG(.jpg/.jpeg)画像形式の完全ガイド — 仕様・マジックナンバー・他形式との比較・EXIF 2026-09-07 07:45:13
- UE5 Get Overlapping Actorsで特定クラスだけ処理|Class Filter・Cast To 2026-09-07 07:45:13
- Linuxで特定拡張子のファイルを再帰削除|find -deleteの安全手順 2026-09-07 07:45:13
- Django CBVでテンプレートに値を渡す|get_context_data・extra_context 2026-09-07 07:45:13
- Linuxで複数ファイルの文字列を一括置換|find・sed・xargsの安全手順 2026-09-07 07:45:13
- Laravelルートグループ|prefix・middleware・nameで一括管理 2026-09-07 07:45:13
- Linux whichコマンドの使い方|絶対パス取得とtype・command -vの違い 2026-09-07 07:45:13
- Linux catコマンドの使い方|行番号表示・複数ファイル連結 2026-09-07 07:45:13
- unable to execute 'gcc': No such file or directory 2026-09-07 07:45:13
コメントを削除してもよろしいでしょうか?