【Python】例外エラーが発生したexcept文の行を取得して表示する方法

Pythonプログラミングをしていると、思わぬエラーに遭遇することがあります。

そんなとき、エラーの詳細情報や発生した行番号を知ることができれば、問題の原因を素早く特定して解決する手助けになります。

この記事では、Pythonで例外エラーが発生した際に、その詳細情報や行番号を取得して表示する方法をわかりやすく解説します。

目次から探す

例外エラーの詳細情報を取得する方法

Pythonでは、プログラムの実行中に発生するエラー(例外)をキャッチして、その詳細情報を取得することができます。

これにより、エラーの原因を特定し、適切な対処を行うことが可能になります。

ここでは、例外エラーの詳細情報を取得するための方法として、sysモジュールとtracebackモジュールの利用方法について解説します。

sysモジュールの利用

Pythonのsysモジュールを使用すると、現在の例外に関する情報を取得することができます。

特に、sys.exc_info()関数は、例外のタイプ、値、およびトレースバックオブジェクトを返します。

sys.exc_info()の使い方

sys.exc_info()は、例外が発生した際にその詳細情報を取得するために使用されます。

この関数は、以下の3つの要素を含むタプルを返します。

  1. 例外のタイプ(例:<class 'ZeroDivisionError'>)
  2. 例外の値(例:division by zero)
  3. トレースバックオブジェクト(例:<traceback object at 0x...>)

以下に、sys.exc_info()を使用した例を示します。

import sys
try:
    1 / 0
except ZeroDivisionError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print(f"例外のタイプ: {exc_type}")
    print(f"例外の値: {exc_value}")
    print(f"トレースバックオブジェクト: {exc_traceback}")

このコードを実行すると、次のような出力が得られます。

例外のタイプ: <class 'ZeroDivisionError'>
例外の値: division by zero
トレースバックオブジェクト: <traceback object at 0x...>

tracebackモジュールの利用

tracebackモジュールを使用すると、例外のトレースバック情報をより詳細に取得することができます。

このモジュールには、例外のトレースバックをフォーマットして文字列として取得するための関数がいくつか用意されています。

traceback.format_exc()の使い方

traceback.format_exc()は、直近の例外のトレースバックを文字列として取得するための関数です。

この関数を使用すると、例外の詳細なトレースバック情報を簡単に取得できます。

以下に、traceback.format_exc()を使用した例を示します。

import traceback
try:
    1 / 0
except ZeroDivisionError:
    tb_str = traceback.format_exc()
    print(tb_str)

このコードを実行すると、次のような出力が得られます。

Traceback (most recent call last):
  File "example.py", line 4, in <module>
    1 / 0
ZeroDivisionError: division by zero

traceback.extract_tb()の使い方

traceback.extract_tb()は、トレースバックオブジェクトからトレースバック情報を抽出し、リストとして返す関数です。

このリストには、各フレームのファイル名、行番号、関数名、およびテキストが含まれます。

以下に、traceback.extract_tb()を使用した例を示します。

import traceback
import sys
try:
    1 / 0
except ZeroDivisionError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    tb_list = traceback.extract_tb(exc_traceback)
    for tb in tb_list:
        print(f"ファイル名: {tb.filename}")
        print(f"行番号: {tb.lineno}")
        print(f"関数名: {tb.name}")
        print(f"テキスト: {tb.line}")

このコードを実行すると、次のような出力が得られます。

ファイル名: example.py
行番号: 4
関数名: <module>
テキスト: 1 / 0

これにより、例外が発生した具体的な場所とその内容を詳細に把握することができます。

例外エラーが発生した行を取得する方法

Pythonでは、例外エラーが発生した際にそのエラーが発生した行番号を取得することができます。

これにより、デバッグが容易になり、エラーの原因を迅速に特定することができます。

ここでは、tracebackモジュールとinspectモジュールを使って行番号を取得する方法を解説します。

tracebackモジュールを使った行番号の取得

tracebackモジュールは、スタックトレースを操作するための標準ライブラリです。

このモジュールを使うことで、例外が発生した行番号を簡単に取得することができます。

traceback.extract_tb()を使った例

traceback.extract_tb()は、トレースバックオブジェクトからスタックトレースの情報を抽出するための関数です。

この関数を使うことで、例外が発生した行番号を含む詳細な情報を取得することができます。

以下は、traceback.extract_tb()を使って例外が発生した行番号を取得する例です。

import traceback
try:
    # 例外を発生させるコード
    1 / 0
except ZeroDivisionError as e:
    # トレースバックオブジェクトを取得
    tb = e.__traceback__
    # トレースバック情報を抽出
    tb_info = traceback.extract_tb(tb)
    # 行番号を取得
    for frame in tb_info:
        print(f"ファイル: {frame.filename}, 行番号: {frame.lineno}, 関数: {frame.name}")

例外エラーの行番号を表示するコード例

上記のコードを実行すると、例外が発生した行番号が表示されます。

具体的には、以下のような出力が得られます。

ファイル: <ipython-input-1-5c6c5e5e5e5e>, 行番号: 4, 関数: <module>

この出力から、例外が発生したファイル名、行番号、および関数名を確認することができます。

inspectモジュールを使った行番号の取得

inspectモジュールは、ライブオブジェクトの情報を取得するための標準ライブラリです。

このモジュールを使うことで、例外が発生した行番号を含む詳細な情報を取得することができます。

inspect.trace()の使い方

inspect.trace()は、現在のスタックトレースを取得するための関数です。

この関数を使うことで、例外が発生した行番号を含む詳細な情報を取得することができます。

以下は、inspect.trace()を使って例外が発生した行番号を取得する例です。

import inspect
try:
    # 例外を発生させるコード
    1 / 0
except ZeroDivisionError as e:
    # スタックトレースを取得
    stack = inspect.trace()
    # 行番号を取得
    for frame in stack:
        print(f"ファイル: {frame.filename}, 行番号: {frame.lineno}, 関数: {frame.function}")

例外エラーの行番号を表示するコード例

上記のコードを実行すると、例外が発生した行番号が表示されます。

具体的には、以下のような出力が得られます。

ファイル: <ipython-input-2-5c6c5e5e5e5e>, 行番号: 4, 関数: <module>

この出力から、例外が発生したファイル名、行番号、および関数名を確認することができます。

以上のように、tracebackモジュールとinspectモジュールを使うことで、例外が発生した行番号を簡単に取得することができます。

これにより、デバッグが容易になり、エラーの原因を迅速に特定することができます。

実践例

ここでは、実際に例外エラーが発生した行を取得して表示する方法を具体的なコード例を通じて解説します。

まずは基本的な例外処理の実装例から始め、その後に例外エラーの行番号を表示する方法、最後に複数の例外を捕捉する方法を紹介します。

基本的な例外処理の実装例

まずは、基本的な例外処理の実装例を見てみましょう。

以下のコードは、ゼロ除算エラーを捕捉するシンプルな例です。

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"エラーが発生しました: {e}")

このコードを実行すると、次のような出力が得られます。

エラーが発生しました: division by zero

この例では、tryブロック内でゼロ除算が発生し、exceptブロックでそのエラーを捕捉してメッセージを表示しています。

例外エラーの行番号を表示する実装例

次に、例外エラーが発生した行番号を表示する方法を見てみましょう。

ここでは、tracebackモジュールを使用します。

import traceback
try:
    result = 10 / 0
except ZeroDivisionError as e:
    tb = traceback.extract_tb(e.__traceback__)
    for frame in tb:
        print(f"ファイル名: {frame.filename}, 行番号: {frame.lineno}, 関数名: {frame.name}")
    print(f"エラーが発生しました: {e}")

このコードを実行すると、次のような出力が得られます。

ファイル名: <ipython-input-1-5c6c6c6c6c6c>, 行番号: 4, 関数名: <module>
エラーが発生しました: division by zero

この例では、traceback.extract_tb()を使用してトレースバックオブジェクトを取得し、その中からファイル名、行番号、関数名を抽出して表示しています。

複数の例外を捕捉する実装例

最後に、複数の例外を捕捉する方法を見てみましょう。

以下のコードは、ゼロ除算エラーと値エラーの両方を捕捉する例です。

import traceback
try:
    value = int("abc")  # ここでValueErrorが発生
    result = 10 / 0     # ここでZeroDivisionErrorが発生
except (ZeroDivisionError, ValueError) as e:
    tb = traceback.extract_tb(e.__traceback__)
    for frame in tb:
        print(f"ファイル名: {frame.filename}, 行番号: {frame.lineno}, 関数名: {frame.name}")
    print(f"エラーが発生しました: {e}")

このコードを実行すると、次のような出力が得られます。

ファイル名: <ipython-input-2-5c6c6c6c6c6c>, 行番号: 4, 関数名: <module>
エラーが発生しました: invalid literal for int() with base 10: 'abc'

この例では、tryブロック内でValueErrorが発生し、exceptブロックでそのエラーを捕捉してメッセージを表示しています。

ZeroDivisionErrorも同様に捕捉されるように設定されていますが、最初に発生したValueErrorが捕捉されます。

これで、例外エラーが発生した行を取得して表示する方法についての解説は終了です。

これらの方法を活用して、デバッグやエラーハンドリングをより効果的に行いましょう。

目次から探す