HOWTO · Python

Python で例外を出力する方法

Python で例外を出力し、メッセージと完全なトレースバックを使い分け、よくある例外処理のミスを避ける方法を説明します。

このページの内容

エラーメッセージだけが必要なら print(exception) を使います。エラーを発生させたファイルと行を含む完全なトレースバックが必要なら、実行中の except ブロック内で traceback.print_exc() を使います。例外の種類を限定して処理し、保存する診断情報には print() ではなくロギングを使います。

例外のメッセージを出力する

例外を変数として受け取り、print() に渡します。何が起きたかを表示する最短の方法です。

try:
    result = 10 / 0
except ZeroDivisionError as exc:
    print("Could not calculate result:", exc)

出力:

Could not calculate result: division by zero

例外オブジェクトはメッセージの文字列に変換されます。この例は ZeroDivisionError だけを捕捉するため、無関係なプログラミングエラーを隠しにくくなります。複数のエラーを同じように扱う場合は、except (TypeError, ValueError) as exc: のように型をタプルで指定します。

完全なトレースバックを出力する

メッセージだけでは、エラーが発生した場所が分からないことがあります。Python 標準の traceback モジュールを読み込み、ハンドラーが有効な間に print_exc() を呼び出します。

import traceback

try:
    values = [1, 2]
    value = values[3]
except IndexError:
    traceback.print_exc()

出力には例外の型、メッセージ、ファイル、失敗した行が含まれます。複数の関数呼び出しを経た例外では、メッセージよりトレースバックの方が役立ちます。

print_exc() は現在処理中の例外を読み取ります。except ブロックの終了後や、例外が有効でないときに呼び出しても過去のトレースバックは復元できず、NoneType: None が出力されることがあります。呼び出しをハンドラー内に置くか、例外を保存して print_exception() を使います。

トレースバックの形式を明示的に制御する

traceback.print_exception() は例外オブジェクトを受け取り、指定したストリームに書き込めます。例外を整形したり転送したりする場合に便利です。

import sys
import traceback

try:
    int("not a number")
except ValueError as exc:
    traceback.print_exception(exc, file=sys.stdout)

すぐに出力せずテキストを作るには、traceback.format_exception(exc) を使います。

import traceback

try:
    raise RuntimeError("configuration is missing")
except RuntimeError as exc:
    formatted = "".join(traceback.format_exception(exc))
    print(formatted)

traceback の関数は既定で例外の連鎖を保持します。そのため raise ... from ... の連鎖では元の例外と新しい例外の両方が表示されます。出力仕様で必要な場合だけトレースバックを制限したり連鎖を無効にしたりしてください。コンテキストを失うと診断が難しくなります。

独自例外とロギング

呼び出し側がドメイン固有の失敗と組み込みエラーを区別する必要がある場合は、独自例外を定義します。その型を捕捉し、同じ方法でメッセージを出力します。

class ConfigurationError(Exception):
    pass

try:
    raise ConfigurationError("API key is missing")
except ConfigurationError as exc:
    print("Configuration failed:", exc)

アプリケーションやサービスでは、ハンドラー内の logging.exception() を優先します。メッセージと有効なトレースバックを記録し、ログの出力先をファイルや監視システムにできます。

import logging

try:
    load_settings()
except Exception:
    logging.exception("Loading settings failed")

load_settings() は失敗する可能性のある処理に置き換えます。この例が広い Exception を捕捉するのはロギング境界だからです。通常の処理では、実際に扱える具体的な例外だけを捕捉します。

よくあるミスと FAQ

  • 型を指定しない except:KeyboardInterruptSystemExit も捕捉します。BaseException のサブクラスを扱う明確な理由がない限り避けます。
  • 有効な結果を作れないのに一般的なメッセージだけを出して黙って続行しないでください。例外を再送出するか、明示的な失敗を返します。
  • type(exc) は具体的なクラス、str(exc) は人が読めるメッセージ、repr(exc) はより診断的な表現を示します。
  • ログに出力するならハンドラー内で logging.exception() を使います。短い対話的な診断なら print(exc) で十分です。
  • traceback.print_exc() は現在処理中の例外用です。例外オブジェクトを保持して形式や出力を制御するなら traceback.print_exception(exc) の方が明確です。

これらは Python 組み込みの例外機構を使うため、サードパーティーパッケージは不要です。必要なのがメッセージ、完全な呼び出し経路、整形済みテキスト、永続的なログのどれかで方法を選びます。