Python
Python3

エラーの情報を取得するmessageとwith_traceback

More than 1 year has passed since last update.


Python 3.6.3 でエラーの情報を取得する際に.messageが使えなかった。

2015年にQiitaにまとめられた記事でpythonの勉強をしていて、エラーの情報を取得する回に


[example.py]

try:

a = 10 / 0
print("{0}".format(a))
except ZeroDivisionError as e:
print("message:{0}".format(e.message))

と処理する際に

Traceback (most recent call last):

File "py3.division_by_zero_info.py", line 9, in <module>
print("message:{0}".format(e.message))
AttributeError: 'ZeroDivisionError' object has no attribute 'message'

とAttributeErrorが出てうまく取得できなかった。


dir()でエラーの持つアトリビュートが調べられる

色々調べまわっていると、dir()でオブジェクトの持つアトリビュートの一覧を確認できることを発見して早速試すと、


[dir.py]

try:

a = 10 / 0
print("{0}".format(a))
except Exception as e:
print(dir(e))

以下、結果

['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', 

'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__',
'__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__',
'args', 'with_traceback']

バーっと出てきた。argsは問題なさそう。messageは見当たらない。

気になるのでバージョンを下げて(2.7.14)、もう一度dir()を試す。

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__',

'__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__',
'__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__',
'args', 'message']

message 発見ーーーー。


messageで出力する

2.7.14のままmessageで出力してみる。


[message.py]

try:

a = 10 / 0
print("{0}".format(a))
except Exception as e:
print("message:{0}".format(e.message))

以下、結果

message:integer division or modulo by zero

ちゃんと取得できた!


with_tracebackで出力する

3.6.3に戻してwith_tracebackで出力する。

with_tracebackを使う場合はsysをimportしてスタックトレース(処理を順番に格納すること?)の情報をexec_info()で取得した上で行う。


[with_traceback.py]

import sys

try:
a = 10 / 0
print("{0}".format(a))
except Exception as e:
tb = sys.exc_info()[2]
print("message:{0}".format(e.with_traceback(tb)))

以下、結果

message:division by zero

無事に出力できた。

情報の内容も少し異なっているし、基底になっているクラスの違いもあるようで(内容が異なっているのかはわかってない)、そういうのも関係しているんでしょうか・・・


お世話になりました。

Python基礎講座(11 例外) - Qiita

Pythonの組み込み例外の木構造を見てみる - Qiita

オブジェクトのアトリビュートの一覧を取得す

5. 組み込み例外 — Python 3.6.3 ドキュメント

29.1. sys — システムパラメータと関数 — Python 3.6.3 ドキュメント